home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume89 / editors / stevie36.2 < prev    next >
Text File  |  1989-05-12  |  63KB  |  2,771 lines

  1. Path: xanth!ukma!tut.cis.ohio-state.edu!rutgers!apple!oliveb!sun!swap!page
  2. From: page%swap@Sun.COM (Bob Page)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v89i131:  stevie - vi editor clone v3.6, Part02/06
  5. Message-ID: <104418@sun.Eng.Sun.COM>
  6. Date: 12 May 89 03:06:25 GMT
  7. Sender: news@sun.Eng.Sun.COM
  8. Lines: 2760
  9. Approved: page@sun.com
  10.  
  11. Submitted-by: grwalter@watmath.waterloo.edu (Fred Walter)
  12. Posting-number: Volume 89, Issue 131
  13. Archive-name: editors/stevie36.2
  14.  
  15. # This is a shell archive.
  16. # Remove anything above and including the cut line.
  17. # Then run the rest of the file through 'sh'.
  18. # Unpacked files will be owned by you and have default permissions.
  19. #----cut here-----cut here-----cut here-----cut here----#
  20. #!/bin/sh
  21. # shar: SHell ARchive
  22. # Run the following text through 'sh' to create:
  23. #    cmdline.c
  24. #    dec.c
  25. #    dos.c
  26. #    dos.h
  27. #    edit.c
  28. #    env.h
  29. #    fileio.c
  30. #    format_l.c
  31. #    help.c
  32. #    inc.c
  33. #    keymap.h
  34. #    linefunc.c
  35. #    macros.h
  36. #    main.c
  37. # This is archive 2 of a 6-part kit.
  38. # This archive created: Thu May 11 19:41:25 1989
  39. echo "extracting cmdline.c"
  40. sed 's/^X//' << \SHAR_EOF > cmdline.c
  41. X/*
  42. X * STEVIE - Simply Try this Editor for VI Enthusiasts
  43. X *
  44. X * Code Contributions By : Tim Thompson           twitch!tjt
  45. X *                         Tony Andrews           onecom!wldrdg!tony 
  46. X *                         G. R. (Fred) Walter    watmath!watcgl!grwalter 
  47. X */
  48. X
  49. X#include "stevie.h"
  50. X
  51. Xstatic char    *altfile = NULL;    /* alternate file */
  52. Xstatic int      altline;    /* line # in alternate file */
  53. X
  54. Xstatic char    *nowrtmsg = "No write since last change (use ! to override)";
  55. X
  56. Xextern char   **files;        /* used for "n" and "rew" */
  57. Xextern int      curfile;
  58. Xextern int      numfiles;
  59. X
  60. X/*
  61. X * The next two variables contain the bounds of any range given in a command.
  62. X * If no range was given, both contain null line pointers. If only a single
  63. X * line was given, u_pos will contain a null line pointer. 
  64. X */
  65. Xstatic LPtr     l_pos, u_pos;
  66. X
  67. Xstatic bool_t   interactive;    /* TRUE if we're reading a real command line */
  68. X
  69. Xstatic bool_t   doecmd();
  70. Xstatic void
  71. Xbadcmd(), doshell(), get_range();
  72. Xstatic LPtr    *get_line();
  73. X
  74. X#ifdef  MEGAMAX
  75. Xoverlay "cmdline"
  76. X#endif
  77. X
  78. X/*
  79. X * readcmdline() - accept a command line starting with ':', '/', or '?' 
  80. X *
  81. X * readcmdline() accepts and processes colon commands and searches. If
  82. X * 'cmdline' is null, the command line is read here. Otherwise, cmdline
  83. X * points to a complete command line that should be used. This is used in
  84. X * main() to handle initialization commands in the environment variable
  85. X * "EXINIT". 
  86. X */
  87. Xvoid
  88. Xreadcmdline(firstc, cmdline)
  89. X    char            firstc;    /* either ':', '/', or '?' */
  90. X    char           *cmdline;    /* optional command string */
  91. X{
  92. X    char            c;
  93. X    char            buff[CMDBUFFSIZE];
  94. X    char            cmdbuf[CMDBUFFSIZE];
  95. X    char            argbuf[CMDBUFFSIZE];
  96. X    char           *p, *q, *cmd, *arg;
  97. X    bool_t          literal_next_flag = FALSE;
  98. X
  99. X    /*
  100. X     * Clear the range variables. 
  101. X     */
  102. X    l_pos.linep = (LINE *) NULL;
  103. X    u_pos.linep = (LINE *) NULL;
  104. X
  105. X    interactive = (cmdline == NULL);
  106. X
  107. X    if (interactive)
  108. X    gotocmdline(YES, firstc);
  109. X    p = buff;
  110. X    if (firstc != ':')
  111. X    *p++ = firstc;
  112. X
  113. X    if (interactive) {
  114. X    /* collect the command string, handling '\b' and @ */
  115. X    for (;;) {
  116. X        c = vgetc();
  117. X        if (c == CTRL('V') && !literal_next_flag) {
  118. X        literal_next_flag = TRUE;
  119. X        outchar('^');
  120. X        continue;
  121. X        }
  122. X        if (c == '\n' || ((c == '\r' || c == ESC) && (!literal_next_flag)))
  123. X        break;
  124. X        if ((c == '\b') && (!literal_next_flag)) {
  125. X        if (p > buff + (firstc != ':')) {
  126. X            p--;
  127. X            /*
  128. X             * this is gross, but it relies only on 'gotocmdline' 
  129. X             */
  130. X            gotocmdline(YES, firstc == ':' ? ':' : NUL);
  131. X            for (q = buff; q < p; q++)
  132. X            outstr(chars[*q].ch_str);
  133. X        } else {
  134. X            msg("");
  135. X            return;    /* back to cmd mode */
  136. X        }
  137. X        continue;
  138. X        }
  139. X        if ((c == '@') && (!literal_next_flag)) {
  140. X        p = buff;
  141. X        gotocmdline(YES, firstc);
  142. X        continue;
  143. X        }
  144. X        if (literal_next_flag) {
  145. X        literal_next_flag = FALSE;
  146. X        outchar('\b');
  147. X        }
  148. X        outstr(chars[c].ch_str);
  149. X        *p++ = c;
  150. X    }
  151. X    *p = '\0';
  152. X    } else {
  153. X    if (strlen(cmdline) > CMDBUFFSIZE - 2)    /* should really do something
  154. X                         * better here... */
  155. X        return;
  156. X    strcpy(p, cmdline);
  157. X    }
  158. X
  159. X    /* skip any initial white space */
  160. X    for (cmd = buff; *cmd != NUL && isspace(*cmd); cmd++);
  161. X
  162. X    /* search commands */
  163. X    c = *cmd;
  164. X    if (c == '/' || c == '?') {
  165. X    cmd++;
  166. X    /* was the command was '//' or '??' (I.E. repeat last search) */
  167. X    if ((*cmd == c) || (*cmd == NUL)) {
  168. X        if (c == '/')
  169. X        searchagain(FORWARD);
  170. X        else
  171. X        searchagain(BACKWARD);
  172. X        return;
  173. X    }
  174. X    /* If there is a matching '/' or '?' at the end, toss it */
  175. X    p = strchr(cmd, NUL);
  176. X    if (*(p - 1) == c && *(p - 2) != '\\')
  177. X        *(p - 1) = NUL;
  178. X    dosearch((c == '/') ? FORWARD : BACKWARD, cmd);
  179. X    return;
  180. X    }
  181. X    /*
  182. X     * Parse a range, if present (and update the cmd pointer). 
  183. X     */
  184. X    get_range(&cmd);
  185. X    if (l_pos.linep != NULL) {
  186. X    if (LINEOF(&l_pos) > LINEOF(&u_pos)) {
  187. X        emsg("Invalid range");
  188. X        return;
  189. X    }
  190. X    }
  191. X    strcpy(cmdbuf, cmd);    /* save the unmodified command */
  192. X
  193. X    /* isolate the command and find any argument */
  194. X    for (p = cmd; *p != NUL && !isspace(*p); p++);
  195. X    if (*p == NUL)
  196. X    arg = NULL;
  197. X    else {
  198. X    *p = NUL;
  199. X    for (p++; *p != NUL && isspace(*p); p++);
  200. X    if (*p == NUL) {
  201. X        arg = NULL;
  202. X    } else {
  203. X        strcpy(argbuf, p);
  204. X        arg = argbuf;
  205. X    }
  206. X    }
  207. X
  208. X    if (strcmp(cmd, "q!") == 0) {
  209. X    getout(0);
  210. X    }
  211. X    if (strcmp(cmd, "q") == 0) {
  212. X    if (Changed) {
  213. X        emsg(nowrtmsg);
  214. X    } else {
  215. X        getout(0);
  216. X    }
  217. X    return;
  218. X    }
  219. X    if (strcmp(cmd, "w") == 0) {
  220. X    if (arg == NULL) {
  221. X        if (Filename != NULL) {
  222. X        if (!writeit(Filename, &l_pos, &u_pos)) {
  223. X            emsg("Problems occured while writing output file");
  224. X        }
  225. X        } else {
  226. X        emsg("No output file");
  227. X        }
  228. X    } else {
  229. X        (void) writeit(arg, &l_pos, &u_pos);
  230. X    }
  231. X    return;
  232. X    }
  233. X    if (strcmp(cmd, "wq") == 0) {
  234. X    if (Filename != NULL) {
  235. X        if (writeit(Filename, (LPtr *) NULL, (LPtr *) NULL)) {
  236. X        getout(0);
  237. X        }
  238. X    } else {
  239. X        emsg("No output file");
  240. X    }
  241. X    return;
  242. X    }
  243. X    if (strcmp(cmd, "x") == 0) {
  244. X    if (Changed) {
  245. X        if (Filename != NULL) {
  246. X        if (!writeit(Filename, (LPtr *) NULL, (LPtr *) NULL)) {
  247. X            emsg("Problems occured while writing output file");
  248. X            return;
  249. X        }
  250. X        } else {
  251. X        emsg("No output file");
  252. X        return;
  253. X        }
  254. X    }
  255. X    getout(0);
  256. X    }
  257. X    if (strcmp(cmd, "f") == 0 && arg == NULL) {
  258. X    fileinfo();
  259. X    return;
  260. X    }
  261. X    if (*cmd == 'n') {
  262. X    if ((curfile + 1) < numfiles) {
  263. X        /*
  264. X         * stuff ":e[!] FILE\n" 
  265. X         */
  266. X        stuffReadbuff(":e");
  267. X        if (cmd[1] == '!')
  268. X        stuffReadbuff("!");
  269. X        stuffReadbuff(" ");
  270. X        stuffReadbuff(files[++curfile]);
  271. X        stuffReadbuff("\n");
  272. X    } else
  273. X        emsg("No more files!");
  274. X    return;
  275. X    }
  276. X    if (*cmd == 'p') {
  277. X    if (curfile > 0) {
  278. X        /*
  279. X         * stuff ":e[!] FILE\n" 
  280. X         */
  281. X        stuffReadbuff(":e");
  282. X        if (cmd[1] == '!')
  283. X        stuffReadbuff("!");
  284. X        stuffReadbuff(" ");
  285. X        stuffReadbuff(files[--curfile]);
  286. X        stuffReadbuff("\n");
  287. X    } else
  288. X        emsg("No more files!");
  289. X    return;
  290. X    }
  291. X    if (strncmp(cmd, "rew", 3) == 0) {
  292. X    if (numfiles <= 1)    /* nothing to rewind */
  293. X        return;
  294. X    curfile = 0;
  295. X    /*
  296. X     * stuff ":e[!] FILE\n" 
  297. X     */
  298. X    stuffReadbuff(":e");
  299. X    if (cmd[3] == '!')
  300. X        stuffReadbuff("!");
  301. X    stuffReadbuff(" ");
  302. X    stuffReadbuff(files[0]);
  303. X    stuffReadbuff("\n");
  304. X    return;
  305. X    }
  306. X    if (strcmp(cmd, "e") == 0) {
  307. X    if (Changed)
  308. X        emsg(nowrtmsg);
  309. X    else
  310. X        (void) doecmd(arg);
  311. X    return;
  312. X    }
  313. X    if (strcmp(cmd, "e!") == 0) {
  314. X    (void) doecmd(arg);
  315. X    return;
  316. X    }
  317. X    if (strcmp(cmd, "f") == 0) {
  318. X    Filename = strsave(arg);
  319. X    filemess("");
  320. X    return;
  321. X    }
  322. X    if (strcmp(cmd, "r") == 0 || strcmp(cmd, ".r") == 0) {
  323. X    if (arg == NULL) {
  324. X        badcmd();
  325. X        return;
  326. X    }
  327. X    if (readfile(arg, Curschar, 1)) {
  328. X        emsg("Can't open file");
  329. X        return;
  330. X    }
  331. X    CHANGED;
  332. X    return;
  333. X    }
  334. X    if (strcmp(cmd, ".=") == 0) {
  335. X    smsg("line %d", cntllines(Filemem, Curschar));
  336. X    return;
  337. X    }
  338. X    if (strcmp(cmd, "$=") == 0) {
  339. X    smsg("%d", cntllines(Filemem, Fileend) - 1);
  340. X    return;
  341. X    }
  342. X    if (strncmp(cmd, "ta", 2) == 0) {
  343. X    dotag(arg, cmd[2] == '!');
  344. X    return;
  345. X    }
  346. X    if (strcmp(cmd, "set") == 0) {
  347. X    doset(arg, interactive);
  348. X    return;
  349. X    }
  350. X    if (strcmp(cmd, "help") == 0) {
  351. X    if (help())
  352. X        s_clear();
  353. X    return;
  354. X    }
  355. X    if (strcmp(cmd, "version") == 0) {
  356. X    extern char    *Version;
  357. X
  358. X    msg(Version);
  359. X    return;
  360. X    }
  361. X    if (strcmp(cmd, "sh") == 0) {
  362. X    doshell();
  363. X    return;
  364. X    }
  365. X    if (strncmp(cmd, "d", 1) == 0) {
  366. X    LINE           *cp;
  367. X    int             n;
  368. X
  369. X    if (l_pos.linep == NULL)
  370. X        l_pos = *Curschar;
  371. X    if (u_pos.linep == NULL)
  372. X        u_pos = l_pos;
  373. X
  374. X    ResetBuffers();
  375. X    n = RowNumber(&l_pos);
  376. X    AppendPositionToUndoUndobuff(0, n);
  377. X    AppendPositionToUndobuff(0, n);
  378. X    if ((Filetop->linep->next == l_pos.linep) &&
  379. X        (u_pos.linep->next == Fileend->linep))
  380. X        AppendToUndobuff("a");
  381. X    else if (u_pos.linep->next == Fileend->linep)
  382. X        AppendToUndobuff("o");
  383. X    else
  384. X        AppendToUndobuff("O");
  385. X
  386. X    n = 0;
  387. X    cp = l_pos.linep;
  388. X    for (; cp != NULL && cp != Fileend->linep; cp = cp->next) {
  389. X        AppendToUndobuff(cp->s);
  390. X        n++;
  391. X        if (cp == u_pos.linep)
  392. X        break;
  393. X        AppendToUndobuff(NL_STR);
  394. X    }
  395. X    AppendToUndobuff(ESC_STR);
  396. X
  397. X    if (n > 1)
  398. X        AppendNumberToUndoUndobuff(n);
  399. X    AppendToUndoUndobuff("dd");
  400. X
  401. X    *Curschar = l_pos;
  402. X    delline(n);
  403. X    S_NOT_VALID;
  404. X    return;
  405. X    }
  406. X    if (strncmp(cmd, "s/", 2) == 0) {
  407. X    dosub(&l_pos, &u_pos, cmdbuf + 1);
  408. X    return;
  409. X    }
  410. X    if (strncmp(cmd, "g/", 2) == 0) {
  411. X    doglob(&l_pos, &u_pos, cmdbuf + 1);
  412. X    return;
  413. X    }
  414. X    /*
  415. X     * If we got a line, but no command, then go to the line. 
  416. X     */
  417. X    if (*cmd == NUL && l_pos.linep != NULL) {
  418. X    if (u_pos.linep != NULL)
  419. X        *Curschar = u_pos;
  420. X    else
  421. X        *Curschar = l_pos;
  422. X
  423. X    S_CHECK_TOPCHAR_AND_BOTCHAR;
  424. X
  425. X    return;
  426. X    }
  427. X    badcmd();
  428. X}
  429. X
  430. X/*
  431. X * get_range - parse a range specifier 
  432. X *
  433. X * Ranges are of the form: 
  434. X *
  435. X * addr[,addr] 
  436. X *
  437. X * where 'addr' is: 
  438. X *
  439. X * %          (entire file)
  440. X * $  [+-NUM]
  441. X * 'x [+-NUM] (where x denotes a currently defined mark)
  442. X * .  [+-NUM]
  443. X * NUM 
  444. X *
  445. X * The pointer *cp is updated to point to the first character following the
  446. X * range spec. If an initial address is found, but no second, the upper bound
  447. X * is equal to the lower. 
  448. X */
  449. Xstatic void
  450. Xget_range(cp)
  451. X    char          **cp;
  452. X{
  453. X    LPtr           *l;
  454. X    char           *p;
  455. X
  456. X    if (**cp == '%') {
  457. X    l_pos.index = 0;
  458. X    l_pos.linep = Filetop->linep->next;
  459. X    u_pos.index = 0;
  460. X    u_pos.linep = Fileend->linep->prev;
  461. X    (*cp)++;
  462. X    return;
  463. X    }
  464. X    if ((l = get_line(cp)) == NULL)
  465. X    return;
  466. X
  467. X    l_pos = *l;
  468. X
  469. X    for (p = *cp; *p != NUL && isspace(*p); p++);
  470. X
  471. X    *cp = p;
  472. X
  473. X    if (*p != ',') {        /* is there another line spec ? */
  474. X    u_pos = l_pos;
  475. X    return;
  476. X    }
  477. X    *cp = ++p;
  478. X
  479. X    if ((l = get_line(cp)) == NULL) {
  480. X    u_pos = l_pos;
  481. X    return;
  482. X    }
  483. X    u_pos = *l;
  484. X}
  485. X
  486. Xstatic LPtr    *
  487. Xget_line(cp)
  488. X    char          **cp;
  489. X{
  490. X    static LPtr     pos;
  491. X    LPtr           *lp;
  492. X    char           *p, c;
  493. X    int             lnum;
  494. X
  495. X    pos.index = 0;        /* shouldn't matter... check back later */
  496. X
  497. X    p = *cp;
  498. X    /*
  499. X     * Determine the basic form, if present. 
  500. X     */
  501. X    switch (c = *p++) {
  502. X
  503. X      case '$':
  504. X    pos.linep = Fileend->linep->prev;
  505. X    break;
  506. X
  507. X      case '.':
  508. X    pos.linep = Curschar->linep;
  509. X    break;
  510. X
  511. X      case '\'':
  512. X    if ((lp = getmark(*p++)) == NULL) {
  513. X        emsg("Unknown mark");
  514. X        return (LPtr *) NULL;
  515. X    }
  516. X    pos = *lp;
  517. X    break;
  518. X
  519. X      case '0':
  520. X      case '1':
  521. X      case '2':
  522. X      case '3':
  523. X      case '4':
  524. X      case '5':
  525. X      case '6':
  526. X      case '7':
  527. X      case '8':
  528. X      case '9':
  529. X    for (lnum = c - '0'; isdigit(*p); p++)
  530. X        lnum = (lnum * 10) + (*p - '0');
  531. X
  532. X    if (lnum == 0)
  533. X        lnum = 1;
  534. X
  535. X    pos = *gotoline(lnum);
  536. X    break;
  537. X
  538. X      default:
  539. X    return (LPtr *) NULL;
  540. X    }
  541. X
  542. X    while (*p != NUL && isspace(*p))
  543. X    p++;
  544. X
  545. X    if (*p == '-' || *p == '+') {
  546. X    bool_t          neg = (*p++ == '-');
  547. X
  548. X    for (lnum = 0; isdigit(*p); p++)
  549. X        lnum = (lnum * 10) + (*p - '0');
  550. X
  551. X    if (neg)
  552. X        lnum = -lnum;
  553. X
  554. X    pos = *gotoline(cntllines(Filemem, &pos) + lnum);
  555. X    }
  556. X    *cp = p;
  557. X    return &pos;
  558. X}
  559. X
  560. Xstatic void
  561. Xbadcmd()
  562. X{
  563. X    if (interactive)
  564. X    emsg("Unrecognized command");
  565. X}
  566. X
  567. X/*
  568. X * dotag(tag, force) - goto tag 
  569. X */
  570. Xvoid
  571. Xdotag(tag, force)
  572. X    char           *tag;
  573. X    bool_t          force;
  574. X{
  575. X    FILE           *tp, *fopen();
  576. X    char            lbuf[LSIZE];
  577. X    char           *fname, *str;
  578. X
  579. X    if ((tp = fopen("tags", "r")) == NULL) {
  580. X    emsg("Can't open tags file");
  581. X    return;
  582. X    }
  583. X    while (fgets(lbuf, LSIZE, tp) != NULL) {
  584. X    if ((fname = strchr(lbuf, TAB)) == NULL) {
  585. X        emsg("Format error in tags file");
  586. X        return;
  587. X    }
  588. X    *fname++ = '\0';
  589. X    if ((str = strchr(fname, TAB)) == NULL) {
  590. X        emsg("Format error in tags file");
  591. X        return;
  592. X    }
  593. X    *str++ = '\0';
  594. X
  595. X    if (strcmp(lbuf, tag) == 0) {
  596. X        if (!force && Changed) {
  597. X        emsg(nowrtmsg);
  598. X        return;
  599. X        }
  600. X        if (doecmd(fname)) {
  601. X        stuffReadbuff(str);    /* str has \n at end */
  602. X        stuffReadbuff("\007");    /* CTRL('G') */
  603. X        fclose(tp);
  604. X        return;
  605. X        }
  606. X    }
  607. X    }
  608. X    emsg("tag not found");
  609. X    fclose(tp);
  610. X}
  611. X
  612. Xstatic          bool_t
  613. Xdoecmd(arg)
  614. X    char           *arg;
  615. X{
  616. X    int             line = 1;    /* line # to go to in new file */
  617. X
  618. X    if (arg != NULL) {
  619. X    /*
  620. X     * First detect a ":e" on the current file. This is mainly for ":ta"
  621. X     * commands where the destination is within the current file. 
  622. X     */
  623. X    if (Filename != NULL) {
  624. X        if (strcmp(arg, Filename) == 0) {
  625. X        if (!Changed) {
  626. X            return TRUE;
  627. X        }
  628. X        }
  629. X    }
  630. X    if (strcmp(arg, "#") == 0) {    /* alternate */
  631. X        char           *s = Filename;
  632. X
  633. X        if (altfile == NULL) {
  634. X        emsg("No alternate file");
  635. X        return FALSE;
  636. X        }
  637. X        Filename = altfile;
  638. X        altfile = s;
  639. X        line = altline;
  640. X        altline = cntllines(Filemem, Curschar);
  641. X    } else {
  642. X        altfile = Filename;
  643. X        altline = cntllines(Filemem, Curschar);
  644. X        Filename = strsave(arg);
  645. X    }
  646. X    }
  647. X    if (Filename == NULL) {
  648. X    emsg("No filename");
  649. X    return FALSE;
  650. X    }
  651. X    /* clear mem and read file */
  652. X    freeall();
  653. X    filealloc();
  654. X    UNCHANGED;
  655. X
  656. X    if (readfile(Filename, Filemem, 0)) {
  657. X    emsg("Can't open file");
  658. X    return FALSE;
  659. X    }
  660. X    *Topchar = *Curschar;
  661. X    if (line != 1) {
  662. X    stuffnumReadbuff(line);
  663. X    stuffReadbuff("G");
  664. X    }
  665. X    setpcmark();
  666. X
  667. X    return TRUE;
  668. X}
  669. X
  670. Xstatic void
  671. Xdoshell()
  672. X{
  673. X    char           *sh, *getenv();
  674. X
  675. X    sh = getenv("SHELL");
  676. X    if (sh == NULL) {
  677. X    emsg("Shell variable not set");
  678. X    return;
  679. X    }
  680. X    gotocmdline(YES, NUL);
  681. X
  682. X    if (system(sh) < 0) {
  683. X    emsg("Exec failed");
  684. X    return;
  685. X    }
  686. X    wait_return();
  687. X}
  688. X
  689. Xvoid
  690. Xgotocmdline(clr, firstc)
  691. X    bool_t          clr;
  692. X    char            firstc;
  693. X{
  694. X    windgoto(Rows - 1, 0);
  695. X    if (clr)
  696. X    outstr(T_EL);        /* clear the bottom line */
  697. X    if (firstc)
  698. X    outchar(firstc);
  699. X}
  700. X
  701. X/*
  702. X * msg(s) - displays the string 's' on the status line 
  703. X */
  704. Xvoid
  705. Xmsg(s)
  706. X    char           *s;
  707. X{
  708. X    gotocmdline(YES, NUL);
  709. X    outstr(s);
  710. X#ifdef AMIGA
  711. X    flushbuf();
  712. X#endif
  713. X#ifdef BSD
  714. X    flushbuf();
  715. X#endif
  716. X}
  717. X
  718. X/* VARARGS */
  719. Xvoid
  720. Xsmsg(s, a1, a2, a3, a4, a5, a6, a7, a8, a9)
  721. X    char           *s;
  722. X    int             a1, a2, a3, a4, a5, a6, a7, a8, a9;
  723. X{
  724. X    char            sbuf[MAX_COLUMNS + 1];
  725. X
  726. X    sprintf(sbuf, s, a1, a2, a3, a4, a5, a6, a7, a8, a9);
  727. X    msg(sbuf);
  728. X}
  729. X
  730. X/*
  731. X * emsg() - display an error message 
  732. X *
  733. X * Rings the bell, if appropriate, and calls message() to do the real work 
  734. X */
  735. Xvoid
  736. Xemsg(s)
  737. X    char           *s;
  738. X{
  739. X    UndoInProgress = FALSE;
  740. X    RedrawingDisabled = FALSE;
  741. X
  742. X    if (P(P_EB))
  743. X    beep();
  744. X    outstr(T_TI);
  745. X    msg(s);
  746. X    outstr(T_TP);
  747. X#ifdef AMIGA
  748. X    flushbuf();
  749. X#endif
  750. X#ifdef BSD
  751. X    flushbuf();
  752. X#endif
  753. X}
  754. X
  755. Xvoid
  756. Xwait_return()
  757. X{
  758. X    char            c;
  759. X
  760. X    outstr("Press RETURN to continue");
  761. X    do {
  762. X    c = vgetc();
  763. X    } while (c != '\r' && c != '\n');
  764. X
  765. X    s_clear();
  766. X}
  767. SHAR_EOF
  768. echo "extracting dec.c"
  769. sed 's/^X//' << \SHAR_EOF > dec.c
  770. X/*
  771. X * STEVIE - Simply Try this Editor for VI Enthusiasts
  772. X *
  773. X * Code Contributions By : Tim Thompson           twitch!tjt
  774. X *                         Tony Andrews           onecom!wldrdg!tony 
  775. X *                         G. R. (Fred) Walter    watmath!watcgl!grwalter 
  776. X */
  777. X
  778. X#include "stevie.h"
  779. X
  780. X/*
  781. X * dec(p) 
  782. X *
  783. X * Decrement the line pointer 'p' crossing line boundaries as necessary. Return
  784. X * 1 when crossing a line, -1 when at start of file, 0 otherwise. 
  785. X */
  786. Xint
  787. Xdec(lp)
  788. X    register LPtr  *lp;
  789. X{
  790. X    if (lp->index > 0) {    /* still within line */
  791. X    lp->index--;
  792. X    return 0;
  793. X    }
  794. X    if (lp->linep->prev != Filetop->linep) {    /* there is a prior line */
  795. X    lp->linep = lp->linep->prev;
  796. X    lp->index = strlen(lp->linep->s);
  797. X    return 1;
  798. X    }
  799. X    lp->index = 0;        /* stick at first char */
  800. X    return -1;            /* at start of file */
  801. X}
  802. SHAR_EOF
  803. echo "extracting dos.c"
  804. sed 's/^X//' << \SHAR_EOF > dos.c
  805. X/*
  806. X * DOS System-dependent routines.
  807. X *
  808. X * System-specific code for MS-DOS. This has been tested with
  809. X * MSDOS 3.3 on an AT. Also, the console driver "nansi.sys" is
  810. X * required.
  811. X *
  812. X */
  813. X
  814. X#include <dos.h>
  815. X#include "stevie.h"
  816. X
  817. X/*
  818. X * inchar() - get a character from the keyboard
  819. X */
  820. Xint
  821. Xinchar()
  822. X{
  823. X    int             c;
  824. X
  825. X    for (;; beep()) {        /* loop until we get a valid character */
  826. X
  827. X    flushbuf();        /* flush any pending output */
  828. X
  829. X    switch (c = getch()) {
  830. X      case 0x1e:
  831. X        return K_CGRAVE;
  832. X      case 0:        /* special key */
  833. X        if (State != NORMAL) {
  834. X        c = getch();    /* throw away next char */
  835. X        continue;    /* and loop for another char */
  836. X        }
  837. X        switch (c = getch()) {
  838. X          case 0x50:
  839. X        return K_DARROW;
  840. X          case 0x48:
  841. X        return K_UARROW;
  842. X          case 0x4b:
  843. X        return K_LARROW;
  844. X          case 0x4d:
  845. X        return K_RARROW;
  846. X          case 0x52:
  847. X        return K_INSERT;
  848. X          case 0x47:
  849. X        stuffReadbuff("1G");
  850. X        return -1;
  851. X          case 0x4f:
  852. X        stuffReadbuff("G");
  853. X        return -1;
  854. X          case 0x51:
  855. X        stuffReadbuff(mkstr(CTRL('F')));
  856. X        return -1;
  857. X          case 0x49:
  858. X        stuffReadbuff(mkstr(CTRL('B')));
  859. X        return -1;
  860. X        /*
  861. X         * Hard-code some useful function key macros. 
  862. X         */
  863. X          case 0x3b:    /* F1 */
  864. X        stuffReadbuff(":p\n");
  865. X        return -1;
  866. X          case 0x54:    /* SF1 */
  867. X        stuffReadbuff(":p!\n");
  868. X        return -1;
  869. X          case 0x3c:    /* F2 */
  870. X        stuffReadbuff(":n\n");
  871. X        return -1;
  872. X          case 0x55:    /* SF2 */
  873. X        stuffReadbuff(":n!\n");
  874. X        return -1;
  875. X          case 0x3d:    /* F3 */
  876. X        stuffReadbuff(":e #\n");
  877. X        return -1;
  878. X          case 0x3e:    /* F4 */
  879. X        stuffReadbuff(":rew\n");
  880. X        return -1;
  881. X          case 0x57:    /* SF4 */
  882. X        stuffReadbuff(":rew!\n");
  883. X        return -1;
  884. X          case 0x3f:    /* F5 */
  885. X        stuffReadbuff("[[");
  886. X        return -1;
  887. X          case 0x40:    /* F6 */
  888. X        stuffReadbuff("]]");
  889. X        return -1;
  890. X          case 0x41:    /* F7 */
  891. X        stuffReadbuff("<<");
  892. X        return -1;
  893. X          case 0x42:    /* F8 */
  894. X        stuffReadbuff(">>");
  895. X        return -1;
  896. X          case 0x43:    /* F9 */
  897. X        stuffReadbuff(":x\n");
  898. X        return -1;
  899. X          case 0x44:    /* F10 */
  900. X        stuffReadbuff(":help\n");
  901. X        return -1;
  902. X          default:
  903. X        break;
  904. X        }
  905. X        break;
  906. X
  907. X      default:
  908. X        return c;
  909. X    }
  910. X    }
  911. X}
  912. X
  913. X#define BSIZE   2048
  914. Xstatic char     outbuf[BSIZE];
  915. Xstatic int      bpos = 0;
  916. X
  917. Xflushbuf()
  918. X{
  919. X    if (bpos != 0)
  920. X    write(1, outbuf, bpos);
  921. X    bpos = 0;
  922. X}
  923. X
  924. X/*
  925. X * Macro to output a character. Used within this file for speed.
  926. X */
  927. X#define outone(c)       outbuf[bpos++] = c; if (bpos >= BSIZE) flushbuf()
  928. X
  929. X/*
  930. X * Function version for use outside this file.
  931. X */
  932. Xvoid
  933. Xoutchar(c)
  934. X    register char   c;
  935. X{
  936. X    outbuf[bpos++] = c;
  937. X    if (bpos >= BSIZE)
  938. X    flushbuf();
  939. X}
  940. X
  941. Xstatic char     cell[2] = {0, 7};
  942. X
  943. X/*
  944. X * outstr(s) - write a string to the console
  945. X */
  946. Xvoid
  947. Xoutstr(s)
  948. X    register char  *s;
  949. X{
  950. X    while (*s) {
  951. X    outone(*s++);
  952. X    }
  953. X}
  954. X
  955. Xvoid
  956. Xbeep()
  957. X{
  958. X    if (RedrawingDisabled)
  959. X    return;
  960. X
  961. X    outone('\007');
  962. X}
  963. X
  964. Xvoid
  965. Xsleep(n)
  966. X    int             n;
  967. X{
  968. X    /*
  969. X     * Should do something reasonable here. 
  970. X     */
  971. X}
  972. X
  973. Xvoid
  974. Xdelay()
  975. X{
  976. X    long            l;
  977. X
  978. X    flushbuf();
  979. X    /*
  980. X     * Should do something better here... 
  981. X     */
  982. X    for (l = 0; l < 5000; l++);
  983. X}
  984. X
  985. Xvoid
  986. Xwindinit()
  987. X{
  988. X    Columns = 80;
  989. X    P(P_LI) = Rows = 25;
  990. X}
  991. X
  992. Xvoid
  993. Xwindexit(r)
  994. X    int             r;
  995. X{
  996. X    flushbuf();
  997. X    exit(r);
  998. X}
  999. X
  1000. Xvoid
  1001. Xwindgoto(r, c)
  1002. X    register int    r, c;
  1003. X{
  1004. X    union REGS      rr;
  1005. X
  1006. X    flushbuf();
  1007. X    rr.h.dh = r;
  1008. X    rr.h.dl = c;
  1009. X    rr.x.bx = 0;
  1010. X    rr.x.ax = 0x0200;
  1011. X    int86(0x10, &rr, &rr);
  1012. X}
  1013. X
  1014. XFILE           *
  1015. Xfopenb(fname, mode)
  1016. X    char           *fname;
  1017. X    char           *mode;
  1018. X{
  1019. X    FILE           *fopen();
  1020. X    char            modestr[16];
  1021. X
  1022. X    sprintf(modestr, "%sb", mode);
  1023. X    return fopen(fname, modestr);
  1024. X}
  1025. SHAR_EOF
  1026. echo "extracting dos.h"
  1027. sed 's/^X//' << \SHAR_EOF > dos.h
  1028. X/*
  1029. X * MS DOS Machine-dependent routines. 
  1030. X */
  1031. X
  1032. Xint  inchar();
  1033. Xvoid outchar();
  1034. Xvoid outstr();
  1035. Xvoid beep();
  1036. Xvoid windinit();
  1037. Xvoid windexit();
  1038. Xvoid windgoto();
  1039. Xvoid delay();
  1040. Xvoid sleep();
  1041. SHAR_EOF
  1042. echo "extracting edit.c"
  1043. sed 's/^X//' << \SHAR_EOF > edit.c
  1044. X/*
  1045. X * STEVIE - Simply Try this Editor for VI Enthusiasts
  1046. X *
  1047. X * Code Contributions By : Tim Thompson           twitch!tjt
  1048. X *                         Tony Andrews           onecom!wldrdg!tony 
  1049. X *                         G. R. (Fred) Walter    watmath!watcgl!grwalter 
  1050. X */
  1051. X
  1052. X#include "stevie.h"
  1053. X
  1054. X/*
  1055. X * This flag is used to make auto-indent work right on lines where only a
  1056. X * <RETURN> or <ESC> is typed. It is set when an auto-indent is done, and
  1057. X * reset when any other editting is done on the line. If an <ESC> or <RETURN>
  1058. X * is received, and did_ai is TRUE, the line is truncated. 
  1059. X */
  1060. Xbool_t          did_ai = FALSE;
  1061. X
  1062. Xvoid
  1063. Xedit()
  1064. X{
  1065. X    char            c;
  1066. X    bool_t          literal_next_flag = FALSE;
  1067. X
  1068. X    Prenum = 0;
  1069. X
  1070. X    /* position the display and the cursor at the top of the file. */
  1071. X    *Topchar = *Filemem;
  1072. X    *Curschar = *Filemem;
  1073. X    Cursrow = Curscol = 0;
  1074. X
  1075. X    s_refresh(NOT_VALID);
  1076. X
  1077. X    for (;;) {
  1078. X
  1079. X    if (!RedrawingDisabled) {
  1080. X        /* Figure out where the cursor is based on Curschar. */
  1081. X        cursupdate(UPDATE_CURSOR);
  1082. X        windgoto(Cursrow, Curscol);
  1083. X    }
  1084. X    c = vgetc();
  1085. X
  1086. X    if (State == NORMAL) {
  1087. X        /* We're in the normal (non-insert) mode. */
  1088. X
  1089. X        /* Pick up any leading digits and compute 'Prenum' */
  1090. X        if (isascii(c)) {    /* must disallow special chars from "ascii.h" */
  1091. X        if ((Prenum > 0 && isdigit(c)) || (isdigit(c) && c != '0')) {
  1092. X            Prenum = Prenum * 10 + (c - '0');
  1093. X            continue;
  1094. X        }
  1095. X        }
  1096. X        /* execute the command */
  1097. X        normal(c);
  1098. X        Prenum = 0;
  1099. X
  1100. X    } else {
  1101. X        if (c == CTRL('V') && !literal_next_flag) {
  1102. X        literal_next_flag = TRUE;
  1103. X        outchar('^');
  1104. X        continue;
  1105. X        }
  1106. X        if (literal_next_flag) {
  1107. X        literal_next_flag = FALSE;
  1108. X        outchar('\b');
  1109. X        if (c != NL) {
  1110. X            did_ai = FALSE;
  1111. X            insertchar(c);
  1112. X            continue;
  1113. X        }
  1114. X        }
  1115. X        switch (c) {    /* We're in insert mode */
  1116. X
  1117. X          case ESC:    /* an escape ends input mode */
  1118. X    doESCkey:
  1119. X        /*
  1120. X         * If we just did an auto-indent, truncate the line, and put
  1121. X         * the cursor back. 
  1122. X         */
  1123. X        if (did_ai) {
  1124. X            Curschar->linep->s[0] = NUL;
  1125. X            Curschar->index = 0;
  1126. X            did_ai = FALSE;
  1127. X        }
  1128. X        set_want_col = TRUE;
  1129. X
  1130. X        /*
  1131. X         * The cursor should end up on the last inserted character.
  1132. X         * This is an attempt to match the real 'vi', but it may not
  1133. X         * be quite right yet. 
  1134. X         */
  1135. X        if (Curschar->index != 0) {
  1136. X            if (gchar(Curschar) == NUL)
  1137. X            dec(Curschar);
  1138. X            else if (Insbuffptr != NULL)
  1139. X            dec(Curschar);
  1140. X        }
  1141. X        State = NORMAL;
  1142. X        msg("");
  1143. X
  1144. X        if (!UndoInProgress) {
  1145. X            int             n;
  1146. X            char           *p;
  1147. X
  1148. X            if (last_command == 'o')
  1149. X            AppendToUndobuff(UNDO_SHIFTJ_STR);
  1150. X
  1151. X            if (Insbuffptr != NULL) {
  1152. X            if (last_command == 'O')
  1153. X                AppendToUndobuff("0");
  1154. X            AppendToRedobuff(Insbuff);
  1155. X            AppendToUndoUndobuff(Insbuff);
  1156. X            n = 0;
  1157. X            for (p = Insbuff; *p != NUL; p++) {
  1158. X                if (*p == NL) {
  1159. X                if (n) {
  1160. X                    AppendNumberToUndobuff(n);
  1161. X                    AppendToUndobuff("dl");
  1162. X                    n = 0;
  1163. X                }
  1164. X                AppendToUndobuff(UNDO_SHIFTJ_STR);
  1165. X                } else
  1166. X                n++;
  1167. X            }
  1168. X            if (n) {
  1169. X                AppendNumberToUndobuff(n);
  1170. X                AppendToUndobuff("dl");
  1171. X            }
  1172. X            }
  1173. X            if (last_command == 'c') {
  1174. X            AppendToUndobuff(mkstr(last_command_char));
  1175. X            AppendToUndobuff(Yankbuff);
  1176. X            AppendToUndobuff(ESC_STR);
  1177. X            }
  1178. X            AppendToRedobuff(ESC_STR);
  1179. X            AppendToUndoUndobuff(ESC_STR);
  1180. X            if (last_command == 'O')
  1181. X            AppendToUndobuff(UNDO_SHIFTJ_STR);
  1182. X        }
  1183. X        break;
  1184. X
  1185. X          case CTRL('D'):
  1186. X        /*
  1187. X         * Control-D is treated as a backspace in insert mode to make
  1188. X         * auto-indent easier. This isn't completely compatible with
  1189. X         * vi, but it's a lot easier than doing it exactly right, and
  1190. X         * the difference isn't very noticeable. 
  1191. X         */
  1192. X          case BS:
  1193. X        /* can't backup past starting point */
  1194. X        if (Curschar->linep == Insstart->linep &&
  1195. X            Curschar->index <= Insstart->index) {
  1196. X            beep();
  1197. X            break;
  1198. X        }
  1199. X        /* can't backup to a previous line */
  1200. X        if (Curschar->linep != Insstart->linep &&
  1201. X            Curschar->index <= 0) {
  1202. X            beep();
  1203. X            break;
  1204. X        }
  1205. X        did_ai = FALSE;
  1206. X        dec(Curschar);
  1207. X        delchar(TRUE, FALSE);
  1208. X        /*
  1209. X         * It's a little strange to put backspaces into the redo
  1210. X         * buffer, but it makes auto-indent a lot easier to deal
  1211. X         * with. 
  1212. X         */
  1213. X        AppendToInsbuff(BS_STR);
  1214. X        if (!RedrawingDisabled)    /* screen will be fixed later */
  1215. X            S_LINE_NOT_VALID;
  1216. X        break;
  1217. X
  1218. X          case CR:
  1219. X          case NL:
  1220. X        AppendToInsbuff(NL_STR);
  1221. X        if (!OpenForward(!RedrawingDisabled))
  1222. X            goto doESCkey;    /* out of memory */
  1223. X        break;
  1224. X
  1225. X          default:
  1226. X        did_ai = FALSE;
  1227. X        insertchar(c);
  1228. X        break;
  1229. X        }
  1230. X    }
  1231. X    }
  1232. X}
  1233. X
  1234. X/*
  1235. X * Special characters in this context are those that need processing other
  1236. X * than the simple insertion that can be performed here. This includes ESC
  1237. X * which terminates the insert, and CR/NL which need special processing to
  1238. X * open up a new line. This routine tries to optimize insertions performed by
  1239. X * the "redo", "undo" or "put" commands, so it needs to know when it should
  1240. X * stop and defer processing to the "normal" mechanism. 
  1241. X */
  1242. X#define ISSPECIAL(c)    ((c) == BS || (c) == NL || (c) == CR || (c) == ESC)
  1243. X
  1244. Xvoid
  1245. Xinsertchar(c)
  1246. X    char            c;
  1247. X{
  1248. X    if (anyinput()) {        /* If there's any pending input, grab up to
  1249. X                 * MAX_COLUMNS at once. */
  1250. X    char            p[MAX_COLUMNS + 1];
  1251. X    int             i;
  1252. X
  1253. X    p[0] = c;
  1254. X    i = 1;
  1255. X    c = vpeekc();
  1256. X    while (!ISSPECIAL(c) && anyinput() && (i < MAX_COLUMNS)) {
  1257. X        p[i++] = vgetc();
  1258. X        c = vpeekc();
  1259. X    }
  1260. X    p[i] = '\0';
  1261. X    insstr(p);
  1262. X    AppendToInsbuff(p);
  1263. X    } else {
  1264. X    inschar(c);
  1265. X    AppendToInsbuff(mkstr(c));
  1266. X    }
  1267. X
  1268. X    if (!RedrawingDisabled)    /* screen will be fixed later */
  1269. X    S_LINE_NOT_VALID;
  1270. X}
  1271. X
  1272. Xvoid
  1273. Xgetout(r)
  1274. X    int             r;
  1275. X{
  1276. X    windgoto(Rows - 1, 0);
  1277. X    outchar('\r');
  1278. X    outchar('\n');
  1279. X    windexit(r);
  1280. X}
  1281. X
  1282. Xvoid
  1283. Xscrolldown(nlines)
  1284. X    int             nlines;
  1285. X{
  1286. X    register LPtr  *p;
  1287. X
  1288. X    S_MUST_UPDATE_BOTCHAR;
  1289. X    S_CHECK_TOPCHAR_AND_BOTCHAR;
  1290. X
  1291. X    /* Scroll up 'nlines' lines. */
  1292. X    while (nlines--) {
  1293. X    p = prevline(Topchar);
  1294. X    if (p == NULL)
  1295. X        break;
  1296. X    Topchar->linep = p->linep;
  1297. X    }
  1298. X    /*
  1299. X     * The calling routine must make sure that Curschar is in the correct
  1300. X     * place with relation to Botchar.
  1301. X     */
  1302. X}
  1303. X
  1304. Xvoid
  1305. Xscrollup(nlines)
  1306. X    int             nlines;
  1307. X{
  1308. X    register LPtr  *p;
  1309. X
  1310. X    S_MUST_UPDATE_BOTCHAR;
  1311. X    S_CHECK_TOPCHAR_AND_BOTCHAR;
  1312. X
  1313. X    /* Scroll down 'nlines' lines. */
  1314. X    while (nlines--) {
  1315. X    p = nextline(Topchar);
  1316. X    if (p == NULL)
  1317. X        break;
  1318. X    Topchar->linep = p->linep;
  1319. X    }
  1320. X    /*
  1321. X     * The calling routine must make sure that Curschar is in the correct
  1322. X     * place with relation to Topchar.
  1323. X     */
  1324. X}
  1325. X
  1326. X/*
  1327. X * oneright oneleft onedown oneup 
  1328. X *
  1329. X * Move one char {right,left,down,up}.  Return TRUE when sucessful, FALSE when
  1330. X * we hit a boundary (of a line, or the file). 
  1331. X */
  1332. X
  1333. Xbool_t
  1334. Xoneright()
  1335. X{
  1336. X    set_want_col = TRUE;
  1337. X
  1338. X    switch (inc(Curschar)) {
  1339. X
  1340. X      case 0:
  1341. X    return TRUE;
  1342. X
  1343. X      case 1:
  1344. X    dec(Curschar);        /* crossed a line, so back up */
  1345. X    /* FALLTHROUGH */
  1346. X      case -1:
  1347. X    return FALSE;
  1348. X    }
  1349. X
  1350. X    return FALSE;        /* PARANOIA: should never reach here */
  1351. X}
  1352. X
  1353. Xbool_t
  1354. Xoneleft()
  1355. X{
  1356. X    set_want_col = TRUE;
  1357. X
  1358. X    switch (dec(Curschar)) {
  1359. X
  1360. X      case 0:
  1361. X    return TRUE;
  1362. X
  1363. X      case 1:
  1364. X    inc(Curschar);        /* crossed a line, so back up */
  1365. X    /* FALLTHROUGH */
  1366. X      case -1:
  1367. X    return FALSE;
  1368. X    }
  1369. X
  1370. X    return FALSE;        /* PARANOIA: should never reach here */
  1371. X}
  1372. X
  1373. Xvoid
  1374. Xbeginline(flag)
  1375. X    bool_t          flag;
  1376. X{
  1377. X    while (oneleft());
  1378. X    if (flag) {
  1379. X    while (isspace(gchar(Curschar)) && oneright());
  1380. X    }
  1381. X    set_want_col = TRUE;
  1382. X}
  1383. X
  1384. Xbool_t
  1385. Xoneup(n)
  1386. X    register int    n;
  1387. X{
  1388. X    register int    k;
  1389. X
  1390. X    S_CHECK_TOPCHAR_AND_BOTCHAR;
  1391. X
  1392. X    for (k = 0; k < n; k++) {
  1393. X    if (Curschar->linep->prev == Filetop->linep) {
  1394. X        if (k > 0)
  1395. X        break;
  1396. X        else
  1397. X        return FALSE;
  1398. X    }
  1399. X    Curschar->linep = Curschar->linep->prev;
  1400. X    }
  1401. X
  1402. X    /* try to advance to the column we want to be at */
  1403. X    Curschar->index = 0;
  1404. X    coladvance(Curschar, Curswant);
  1405. X    return TRUE;
  1406. X}
  1407. X
  1408. Xbool_t
  1409. Xonedown(n)
  1410. X    register int    n;
  1411. X{
  1412. X    register int    k;
  1413. X
  1414. X    S_CHECK_TOPCHAR_AND_BOTCHAR;
  1415. X
  1416. X    for (k = 0; k < n; k++) {
  1417. X    if (Curschar->linep->next == Fileend->linep) {
  1418. X        if (k > 0)
  1419. X        break;
  1420. X        else
  1421. X        return FALSE;
  1422. X    }
  1423. X    Curschar->linep = Curschar->linep->next;
  1424. X    }
  1425. X
  1426. X    /* try to advance to the column we want to be at */
  1427. X    Curschar->index = 0;
  1428. X    coladvance(Curschar, Curswant);
  1429. X    return TRUE;
  1430. X}
  1431. SHAR_EOF
  1432. echo "extracting env.h"
  1433. sed 's/^X//' << \SHAR_EOF > env.h
  1434. X/*
  1435. X * STEVIE - Simply Try this Editor for VI Enthusiasts
  1436. X *
  1437. X * Code Contributions By : Tim Thompson           twitch!tjt
  1438. X *                         Tony Andrews           onecom!wldrdg!tony 
  1439. X *                         G. R. (Fred) Walter    watmath!watcgl!grwalter 
  1440. X */
  1441. X
  1442. X/*
  1443. X * The defines in this file establish the environment we're compiling
  1444. X * in. Set these appropriately before compiling the editor.
  1445. X */
  1446. X
  1447. X/*
  1448. X * One (and only 1) of the following defines should be uncommented. Most of
  1449. X * the code is pretty machine-independent. Machine dependent code goes in a
  1450. X * file like tos.c or unix.c. The only other place where machine dependent
  1451. X * code goes is term.h for escape sequences. 
  1452. X */
  1453. X
  1454. X#ifndef AMIGA
  1455. X# ifndef BSD
  1456. X#  ifndef UNIX
  1457. X/* Defined in makefile : AMIGA    Amiga */
  1458. X/* Defined in makefile : BSD    BSD 4.3 */
  1459. X/* Defined in makefile : UNIX    System V */
  1460. X/* #define    ATARI        Atari ST */
  1461. X/* #define    OS2        Microsoft OS/2 */
  1462. X/* #define    DOS        MS DOS 3.3 */
  1463. X#  endif
  1464. X# endif
  1465. X#endif
  1466. X
  1467. X/*
  1468. X * If ATARI is defined, one of the following compilers must be selected. 
  1469. X */
  1470. X#ifdef    ATARI
  1471. X#define MWC            Mark William's C 3.0.9 */
  1472. X/* #define    MEGAMAX        Megamax Compiler */
  1473. X/* #define    ALCYON        Alcyon C compiler */
  1474. X
  1475. X# ifdef MWC
  1476. X#  define AppendNumberToUndoUndobuff     XX1
  1477. X#  define AppendPositionToUndoUndobuff    XX2
  1478. X#  define FOPENB
  1479. X# endif
  1480. X
  1481. X# ifdef MEGAMAX
  1482. X#  define FOPENB
  1483. X# endif
  1484. X#endif
  1485. X
  1486. X/*
  1487. X * If HELP is defined, the :help command shows a vi command summary. 
  1488. X */
  1489. X#define    HELP            /* enable help command */
  1490. X
  1491. X/*
  1492. X * STRCSPN should be defined if the target system doesn't have the
  1493. X * routine strcspn() available. See regexp.c for details.
  1494. X */
  1495. X
  1496. X#ifdef    ATARI
  1497. X#define    STRCSPN
  1498. X#endif
  1499. SHAR_EOF
  1500. echo "extracting fileio.c"
  1501. sed 's/^X//' << \SHAR_EOF > fileio.c
  1502. X/*
  1503. X * STEVIE - Simply Try this Editor for VI Enthusiasts
  1504. X *
  1505. X * Code Contributions By : Tim Thompson           twitch!tjt
  1506. X *                         Tony Andrews           onecom!wldrdg!tony 
  1507. X *                         G. R. (Fred) Walter    watmath!watcgl!grwalter 
  1508. X */
  1509. X
  1510. X#include "stevie.h"
  1511. X
  1512. Xvoid
  1513. Xfilemess(s)
  1514. X    char           *s;
  1515. X{
  1516. X    sprintf(IObuff, "\"%s\" %s", ((Filename == NULL) ? "" : Filename), s);
  1517. X    msg(IObuff);
  1518. X}
  1519. X
  1520. Xvoid
  1521. Xrenum()
  1522. X{
  1523. X    LPtr           *p;
  1524. X    unsigned long   l = 0;
  1525. X
  1526. X    for (p = Filemem; p != NULL; p = nextline(p), l += LINEINC)
  1527. X    p->linep->num = l;
  1528. X
  1529. X    Fileend->linep->num = 0xffffffffL;
  1530. X}
  1531. X
  1532. X#ifdef  MEGAMAX
  1533. Xoverlay "fileio"
  1534. X#endif
  1535. X
  1536. Xbool_t
  1537. Xreadfile(fname, fromp, nochangename)
  1538. X    char           *fname;
  1539. X    LPtr           *fromp;
  1540. X    bool_t          nochangename;    /* if TRUE, don't change the Filename */
  1541. X{
  1542. X    FILE           *f, *fopen();
  1543. X    LINE           *curr;
  1544. X    char            buf2[80];
  1545. X    int             c;
  1546. X    int             IObuffsize = 0;
  1547. X    long            nchars = 0;
  1548. X    int             linecnt = 0;
  1549. X    bool_t          wasempty = bufempty();
  1550. X    int             nonascii = 0;    /* count garbage characters */
  1551. X    int             nulls = 0;    /* count nulls */
  1552. X    bool_t          incomplete = FALSE;    /* was the last line incomplete? */
  1553. X    bool_t          toolong = FALSE;    /* a line was too long */
  1554. X
  1555. X    curr = fromp->linep;
  1556. X
  1557. X    if (!nochangename)
  1558. X    Filename = strsave(fname);
  1559. X
  1560. X    f = fopen(fname, "r");
  1561. X    if (f == NULL)
  1562. X    return TRUE;
  1563. X
  1564. X    S_NOT_VALID;
  1565. X
  1566. X    filemess("");
  1567. X
  1568. X    do {
  1569. X    c = getc(f);
  1570. X
  1571. X    if (c == EOF) {
  1572. X        if (IObuffsize == 0)/* normal loop termination */
  1573. X        break;
  1574. X
  1575. X        /*
  1576. X         * If we get EOF in the middle of a line, note the fact and
  1577. X         * complete the line ourselves. 
  1578. X         */
  1579. X        incomplete = TRUE;
  1580. X        c = NL;
  1581. X    }
  1582. X    if (c >= 0x80) {
  1583. X        c -= 0x80;
  1584. X        nonascii++;
  1585. X    }
  1586. X    /*
  1587. X     * If we reached the end of the line, OR we ran out of space for it,
  1588. X     * then process the complete line. 
  1589. X     */
  1590. X    if (c == NL || IObuffsize == (IOSIZE - 1)) {
  1591. X        LINE           *lp;
  1592. X
  1593. X        if (c != NL)
  1594. X        toolong = TRUE;
  1595. X
  1596. X        IObuff[IObuffsize++] = NUL;
  1597. X        lp = newline(IObuffsize);
  1598. X        if (lp == NULL) {
  1599. X        fprintf(stderr, "not enough memory - should never happen");
  1600. X        getout(1);
  1601. X        }
  1602. X        strcpy(lp->s, IObuff);
  1603. X
  1604. X        curr->next->prev = lp;    /* new line to next one */
  1605. X        lp->next = curr->next;
  1606. X
  1607. X        curr->next = lp;    /* new line to prior one */
  1608. X        lp->prev = curr;
  1609. X
  1610. X        curr = lp;        /* new line becomes current */
  1611. X        IObuffsize = 0;
  1612. X        linecnt++;
  1613. X    } else if (c == NUL) {
  1614. X        nulls++;        /* count and ignore nulls */
  1615. X    } else {
  1616. X        IObuff[IObuffsize++] = (char) c;    /* normal character */
  1617. X    }
  1618. X
  1619. X    nchars++;
  1620. X    } while (!incomplete && !toolong);
  1621. X
  1622. X    fclose(f);
  1623. X
  1624. X    /*
  1625. X     * If the buffer was empty when we started, we have to go back and remove
  1626. X     * the "dummy" line at Filemem and patch up the ptrs. 
  1627. X     */
  1628. X    if (wasempty && linecnt != 0) {
  1629. X    LINE           *dummy = Filemem->linep;    /* dummy line ptr */
  1630. X
  1631. X    Filemem->linep = Filemem->linep->next;
  1632. X    Filemem->linep->prev = Filetop->linep;
  1633. X    Filetop->linep->next = Filemem->linep;
  1634. X
  1635. X    Curschar->linep = Filemem->linep;
  1636. X    Topchar->linep = Filemem->linep;
  1637. X
  1638. X    free(dummy->s);        /* free string space */
  1639. X    free((char *) dummy);    /* free LINE struct */
  1640. X    }
  1641. X    renum();
  1642. X
  1643. X    if (toolong) {
  1644. X    sprintf(IObuff, "\"%s\" Line too long", fname);
  1645. X    msg(IObuff);
  1646. X    return FALSE;
  1647. X    }
  1648. X    sprintf(IObuff, "\"%s\" %s%d line%s, %ld character%s",
  1649. X        fname,
  1650. X        incomplete ? "[Incomplete last line] " : "",
  1651. X        linecnt, (linecnt > 1) ? "s" : "",
  1652. X        nchars, (nchars > 1) ? "s" : "");
  1653. X
  1654. X    buf2[0] = NUL;
  1655. X
  1656. X    if (nonascii || nulls) {
  1657. X    if (nonascii) {
  1658. X        if (nulls)
  1659. X        sprintf(buf2, " (%d null, %d non-ASCII)",
  1660. X            nulls, nonascii);
  1661. X        else
  1662. X        sprintf(buf2, " (%d non-ASCII)", nonascii);
  1663. X    } else
  1664. X        sprintf(buf2, " (%d null)", nulls);
  1665. X    }
  1666. X    strcat(IObuff, buf2);
  1667. X    msg(IObuff);
  1668. X
  1669. X    return FALSE;
  1670. X}
  1671. X
  1672. X/*
  1673. X * writeit - write to file 'fname' lines 'start' through 'end' 
  1674. X *
  1675. X * If either 'start' or 'end' contain null line pointers, the default is to use
  1676. X * the start or end of the file respectively. 
  1677. X */
  1678. Xbool_t
  1679. Xwriteit(fname, start, end)
  1680. X    char           *fname;
  1681. X    LPtr           *start, *end;
  1682. X{
  1683. X    FILE           *f;
  1684. X    FILE           *fopen();
  1685. X    FILE           *fopenb();    /* open in binary mode, where needed */
  1686. X    char           *s;
  1687. X    long            nchars;
  1688. X    int             lines;
  1689. X    LPtr           *p;
  1690. X
  1691. X    sprintf(IObuff, "\"%s\"", fname);
  1692. X    msg(IObuff);
  1693. X
  1694. X    /*
  1695. X     * Form the backup file name - change foo.* to foo.bak - use IObuff to
  1696. X     * hold the backup file name 
  1697. X     */
  1698. X    strcpy(IObuff, fname);
  1699. X    for (s = IObuff; *s && *s != '.'; s++);
  1700. X    *s = NUL;
  1701. X    strcat(IObuff, ".bak");
  1702. X
  1703. X    /*
  1704. X     * Delete any existing backup and move the current version to the backup.
  1705. X     * For safety, we don't remove the backup until the write has finished
  1706. X     * successfully. And if the 'backup' option is set, leave it around. 
  1707. X     */
  1708. X    rename(fname, IObuff);
  1709. X
  1710. X    f = P(P_CR) ? fopen(fname, "w") : fopenb(fname, "w");
  1711. X    if (f == NULL) {
  1712. X    emsg("Can't open file for writing!");
  1713. X    return FALSE;
  1714. X    }
  1715. X    /*
  1716. X     * If we were given a bound, start there. Otherwise just start at the
  1717. X     * beginning of the file. 
  1718. X     */
  1719. X    if (start == NULL || start->linep == NULL)
  1720. X    p = Filemem;
  1721. X    else
  1722. X    p = start;
  1723. X
  1724. X    lines = 0;
  1725. X    nchars = 0;
  1726. X    do {
  1727. X    fprintf(f, "%s\n", p->linep->s);
  1728. X    nchars += strlen(p->linep->s) + 1;
  1729. X    lines++;
  1730. X
  1731. X    /*
  1732. X     * If we were given an upper bound, and we just did that line, then
  1733. X     * bag it now. 
  1734. X     */
  1735. X    if (end != NULL && end->linep != NULL) {
  1736. X        if (end->linep == p->linep)
  1737. X        break;
  1738. X    }
  1739. X    } while ((p = nextline(p)) != NULL);
  1740. X
  1741. X    fclose(f);
  1742. X
  1743. X    /*
  1744. X     * Remove the backup unless they want it left around 
  1745. X     */
  1746. X    if (!P(P_BK))
  1747. X    remove(IObuff);
  1748. X
  1749. X    sprintf(IObuff, "\"%s\" %d line%s, %ld character%s", fname,
  1750. X        lines, (lines > 1) ? "s" : "",
  1751. X        nchars, (nchars > 1) ? "s" : "");
  1752. X    msg(IObuff);
  1753. X    UNCHANGED;
  1754. X
  1755. X    return TRUE;
  1756. X}
  1757. SHAR_EOF
  1758. echo "extracting format_l.c"
  1759. sed 's/^X//' << \SHAR_EOF > format_l.c
  1760. X/*
  1761. X * format_line() 
  1762. X *
  1763. X * Return a pointer to a string buffer containing a formated screen line.
  1764. X *
  1765. X * By G. R. (Fred) Walter    watmath!watcgl!grwalter 
  1766. X */
  1767. X
  1768. X#include "stevie.h"
  1769. X
  1770. Xchar           *tab_expand = "                ";
  1771. X
  1772. Xchar           *
  1773. Xformat_line(ptr, len)
  1774. X    register char  *ptr;
  1775. X    int            *len;
  1776. X{
  1777. X    register char  *dest;
  1778. X    register char   c;
  1779. X    register int    col;
  1780. X    char           *p_extra;
  1781. X    int             n_extra;
  1782. X    int             coff;    /* column offset */
  1783. X
  1784. X    dest = IObuff;
  1785. X    col = 0;
  1786. X
  1787. X    coff = P(P_NU) ? 8 : 0;
  1788. X
  1789. X    n_extra = 0;
  1790. X    p_extra = NULL;
  1791. X
  1792. X    for (;;) {
  1793. X    if (n_extra > 0) {
  1794. X        c = *p_extra++;
  1795. X        n_extra--;
  1796. X    } else {
  1797. X        c = *ptr++;
  1798. X        while (c >= 32 && c < 127) {
  1799. X        *dest++ = c;
  1800. X        col++;
  1801. X        if (col >= IOSIZE)
  1802. X            goto DONE_FORMAT_LINE;
  1803. X        c = *ptr++;
  1804. X        }
  1805. X        if (c == TAB) {
  1806. X        if (!P(P_LS)) {
  1807. X            /* tab amount depends on current column */
  1808. X            p_extra = tab_expand;
  1809. X            n_extra = (P(P_TS) - 1) - (col - coff) % P(P_TS);
  1810. X            c = ' ';
  1811. X        }
  1812. X        } else if ((n_extra = chars[c].ch_size - 1) > 0) {
  1813. X        p_extra = chars[c].ch_str;
  1814. X        c = *p_extra++;
  1815. X        } else if (c == NUL) {
  1816. X        if (P(P_NU)) {
  1817. X            *dest++ = '$';
  1818. X            col++;
  1819. X        }
  1820. X        break;
  1821. X        }
  1822. X    }
  1823. X    *dest++ = c;
  1824. X    col++;
  1825. X    if (col >= IOSIZE)
  1826. X        break;
  1827. X    }
  1828. XDONE_FORMAT_LINE:
  1829. X    if (col >= IOSIZE) {
  1830. X    dest--;
  1831. X    col--;
  1832. X    }
  1833. X    *dest = NUL;
  1834. X
  1835. X    if (len != NULL)
  1836. X    *len = col;
  1837. X
  1838. X    return (IObuff);
  1839. X}
  1840. SHAR_EOF
  1841. echo "extracting help.c"
  1842. sed 's/^X//' << \SHAR_EOF > help.c
  1843. X/*
  1844. X * STEVIE - Simply Try this Editor for VI Enthusiasts
  1845. X *
  1846. X * Code Contributions By : Tim Thompson           twitch!tjt
  1847. X *                         Tony Andrews           onecom!wldrdg!tony 
  1848. X *                         G. R. (Fred) Walter    watmath!watcgl!grwalter 
  1849. X */
  1850. X
  1851. X#include "stevie.h"
  1852. X
  1853. Xextern char    *Version;
  1854. X
  1855. Xstatic int      helprow;
  1856. X
  1857. X#ifdef  HELP
  1858. X
  1859. X#ifdef  MEGAMAX
  1860. Xoverlay "help"
  1861. X#endif
  1862. X
  1863. Xstatic void     longline();
  1864. X
  1865. Xbool_t
  1866. Xhelp()
  1867. X{
  1868. X    outstr(T_ED);
  1869. X    windgoto(helprow = 0, 0);
  1870. X
  1871. X    longline("\
  1872. XPositioning within file\n\
  1873. X=======================\n\
  1874. X^F\t\tForward screenfull             Worked on by:\n\
  1875. X^B\t\tBackward screenfull                Tim Thompson\n");
  1876. X    longline("\
  1877. X^D\t\tscroll down half screen            Tony Andrews\n\
  1878. X^U\t\tscroll up half screen              G.R. (Fred) Walter\n");
  1879. X    longline("\
  1880. XG\t\tGoto line (end default)\n\
  1881. X]]\t\tnext function\n\
  1882. X[[\t\tprevious function\n\
  1883. X/re\t\tnext occurence of regular expression 're'\n");
  1884. X    longline("\
  1885. X?re\t\tprior occurence of regular expression 're'\n\
  1886. Xn\t\trepeat last / or ?\n\
  1887. XN\t\treverse last / or ?\n\
  1888. X%\t\tfind matching (, ), {, }, [, or ]\n");
  1889. X    longline("\
  1890. X\n\
  1891. XAdjusting the screen\n\
  1892. X====================\n\
  1893. X^L\t\tRedraw the screen\n\
  1894. X^E\t\tscroll window down 1 line\n\
  1895. X^Y\t\tscroll window up 1 line\n");
  1896. X    longline("\
  1897. Xz<RETURN>\tredraw, current line at top\n\
  1898. Xz-\t\t... at bottom\n\
  1899. Xz.\t\t... at center\n");
  1900. X
  1901. X    windgoto(0, 32);
  1902. X    longline(Version);
  1903. X#ifdef AMIGA
  1904. X    longline(" ");
  1905. X    longline(__DATE__);
  1906. X    longline(" ");
  1907. X    longline(__TIME__);
  1908. X#endif
  1909. X
  1910. X    windgoto(helprow = Rows - 2, 47);
  1911. X    longline("<Press space bar to continue>\n");
  1912. X    windgoto(helprow = Rows - 1, 47);
  1913. X    longline("<Any other key will quit>");
  1914. X
  1915. X    if (vgetc() != ' ')
  1916. X    return TRUE;
  1917. X
  1918. X    outstr(T_ED);
  1919. X    windgoto(helprow = 0, 0);
  1920. X
  1921. X    longline("\
  1922. XCharacter Positioning\n\
  1923. X=====================\n\
  1924. X^\t\tfirst non-white\n\
  1925. X0\t\tbeginning of line\n\
  1926. X$\t\tend of line\n\
  1927. Xh\t\tbackward\n");
  1928. X    longline("\
  1929. Xl\t\tforward\n\
  1930. X^H\t\tsame as h\n\
  1931. Xspace\t\tsame as l\n\
  1932. Xfx\t\tfind 'x' forward\n");
  1933. X    longline("\
  1934. XFx\t\tfind 'x' backward\n\
  1935. Xtx\t\tupto 'x' forward\n\
  1936. XTx\t\tupto 'x' backward\n\
  1937. X;\t\tRepeat last f, F, t, or T\n");
  1938. X    longline("\
  1939. X,\t\tinverse of ;\n\
  1940. X|\t\tto specified column\n\
  1941. X%\t\tfind matching (, ), {, }, [, or ]\n");
  1942. X
  1943. X    windgoto(helprow = Rows - 2, 47);
  1944. X    longline("<Press space bar to continue>\n");
  1945. X    windgoto(helprow = Rows - 1, 47);
  1946. X    longline("<Any other key will quit>");
  1947. X
  1948. X    if (vgetc() != ' ')
  1949. X    return TRUE;
  1950. X
  1951. X    outstr(T_ED);
  1952. X    windgoto(helprow = 0, 0);
  1953. X
  1954. X    longline("\
  1955. XLine Positioning\n\
  1956. X================\n\
  1957. XH\t\thome window line\n\
  1958. XL\t\tlast window line\n\
  1959. XM\t\tmiddle window line\n");
  1960. X    longline("\
  1961. X+\t\tnext line, at first non-white\n\
  1962. X-\t\tprevious line, at first non-white\n\
  1963. XCR\t\treturn, same as +\n\
  1964. Xj\t\tnext line, same column\n\
  1965. Xk\t\tprevious line, same column\n");
  1966. X
  1967. X    longline("\
  1968. X\n\
  1969. XMarking and Returning\n\
  1970. X=====================\n\
  1971. X``\t\tprevious context\n\
  1972. X''\t\t... at first non-white in line\n");
  1973. X    longline("\
  1974. Xmx\t\tmark position with letter 'x'\n\
  1975. X`x\t\tto mark 'x'\n\
  1976. X'x\t\t... at first non-white in line\n");
  1977. X
  1978. X    windgoto(helprow = Rows - 2, 47);
  1979. X    longline("<Press space bar to continue>\n");
  1980. X    windgoto(helprow = Rows - 1, 47);
  1981. X    longline("<Any other key will quit>");
  1982. X
  1983. X    if (vgetc() != ' ')
  1984. X    return TRUE;
  1985. X
  1986. X    outstr(T_ED);
  1987. X    windgoto(helprow = 0, 0);
  1988. X
  1989. X    longline("\
  1990. XInsert and Replace\n\
  1991. X==================\n\
  1992. Xa\t\tappend after cursor\n\
  1993. Xi\t\tinsert before cursor\n\
  1994. XA\t\tappend at end of line\n\
  1995. XI\t\tinsert before first non-blank\n");
  1996. X    longline("\
  1997. Xo\t\topen line below\n\
  1998. XO\t\topen line above\n\
  1999. Xrx\t\treplace single char with 'x'\n\
  2000. XR\t\treplace characters (not yet)\n\
  2001. X~\t\treplace character under cursor with other case\n");
  2002. X
  2003. X    longline("\
  2004. X\n\
  2005. XWords, sentences, paragraphs\n\
  2006. X============================\n\
  2007. Xw\t\tword forward\n\
  2008. Xb\t\tback word\n\
  2009. Xe\t\tend of word\n\
  2010. X)\t\tto next sentence (not yet)\n\
  2011. X}\t\tto next paragraph (not yet)\n");
  2012. X    longline("\
  2013. X(\t\tback sentence (not yet)\n\
  2014. X{\t\tback paragraph (not yet)\n\
  2015. XW\t\tblank delimited word\n\
  2016. XB\t\tback W\n\
  2017. XE\t\tto end of W");
  2018. X
  2019. X    windgoto(helprow = Rows - 2, 47);
  2020. X    longline("<Press space bar to continue>\n");
  2021. X    windgoto(helprow = Rows - 1, 47);
  2022. X    longline("<Any other key will quit>");
  2023. X
  2024. X    if (vgetc() != ' ')
  2025. X    return TRUE;
  2026. X
  2027. X    outstr(T_ED);
  2028. X    windgoto(helprow = 0, 0);
  2029. X
  2030. X    longline("\
  2031. XUndo  &  Redo\n\
  2032. X=============\n\
  2033. Xu\t\tundo last change\n\
  2034. XU\t\trestore current line (not yet)\n\
  2035. X.\t\trepeat last change\n");
  2036. X
  2037. X    longline("\
  2038. X\n\
  2039. XFile manipulation\n\
  2040. X=================\n");
  2041. X    longline("\
  2042. X:w\t\twrite back changes\n\
  2043. X:wq\t\twrite and quit\n\
  2044. X:x\t\twrite if modified, and quit\n\
  2045. X:q\t\tquit\n\
  2046. X:q!\t\tquit, discard changes\n\
  2047. X:e name\t\tedit file 'name'\n");
  2048. X    longline("\
  2049. X:e!\t\tre-edit, discard changes\n\
  2050. X:e #\t\tedit alternate file\n\
  2051. X:w name\t\twrite file 'name'\n");
  2052. X    longline("\
  2053. X:n\t\tedit next file in arglist\n\
  2054. X:n args\t\tspecify new arglist (not yet)\n\
  2055. X:rew\t\trewind arglist\n\
  2056. X:f\t\thow current file and lines\n");
  2057. X    longline("\
  2058. X:f file\t\tchange current file name\n\
  2059. X:ta tag\t\tto tag file entry 'tag'\n\
  2060. X^]\t\t:ta, current word is tag");
  2061. X
  2062. X    windgoto(helprow = Rows - 2, 47);
  2063. X    longline("<Press space bar to continue>\n");
  2064. X    windgoto(helprow = Rows - 1, 47);
  2065. X    longline("<Any other key will quit>");
  2066. X
  2067. X    if (vgetc() != ' ')
  2068. X    return TRUE;
  2069. X
  2070. X    outstr(T_ED);
  2071. X    windgoto(helprow = 0, 0);
  2072. X
  2073. X    longline("\
  2074. XOperators (double to affect lines)\n\
  2075. X==================================\n\
  2076. Xd\t\tdelete\n\
  2077. Xc\t\tchange\n");
  2078. X    longline("\
  2079. X<\t\tleft shift\n\
  2080. X>\t\tright shift\n\
  2081. Xy\t\tyank to buffer\n");
  2082. X
  2083. X    longline("\n\
  2084. XYank and Put\n\
  2085. X============\n\
  2086. Xp\t\tput back text\n\
  2087. XP\t\tput before\n\
  2088. XY\t\tyank lines");
  2089. X
  2090. X    windgoto(helprow = Rows - 2, 47);
  2091. X    longline("<Press space bar to continue>\n");
  2092. X    windgoto(helprow = Rows - 1, 47);
  2093. X    longline("<Any other key will quit>");
  2094. X
  2095. X    if (vgetc() != ' ')
  2096. X    return TRUE;
  2097. X
  2098. X    outstr(T_ED);
  2099. X    windgoto(helprow = 0, 0);
  2100. X
  2101. X    longline("\n\
  2102. XMiscellaneous operations\n\
  2103. X========================\n\
  2104. XC\t\tchange rest of line\n\
  2105. XD\t\tdelete rest of line\n\
  2106. Xs\t\tsubstitute chars\n");
  2107. X    longline("\
  2108. XS\t\tsubstitute lines (not yet)\n\
  2109. XJ\t\tjoin lines\n\
  2110. Xx\t\tdelete characters\n\
  2111. XX\t\t... before cursor\n\
  2112. X:[range]s/search/replace/[g]\n\
  2113. X:[range]g/search[/p|/d]\n\
  2114. X:[range]d\tdelete range of lines\n");
  2115. X
  2116. X    windgoto(helprow = Rows - 1, 47);
  2117. X    longline("<Press any key>");
  2118. X
  2119. X    vgetc();
  2120. X
  2121. X    return TRUE;
  2122. X}
  2123. X
  2124. Xstatic void
  2125. Xlongline(p)
  2126. X    char           *p;
  2127. X{
  2128. X# ifdef AMIGA
  2129. X    outstr(p);
  2130. X# else
  2131. X    char           *s;
  2132. X
  2133. X    for (s = p; *s; s++) {
  2134. X    if (*s == '\n')
  2135. X        windgoto(++helprow, 0);
  2136. X    else
  2137. X        outchar(*s);
  2138. X    }
  2139. X# endif
  2140. X}
  2141. X#else
  2142. X
  2143. Xbool_t
  2144. Xhelp()
  2145. X{
  2146. X    msg("Sorry, help not configured");
  2147. X    return FALSE;
  2148. X}
  2149. X#endif
  2150. SHAR_EOF
  2151. echo "extracting inc.c"
  2152. sed 's/^X//' << \SHAR_EOF > inc.c
  2153. X/*
  2154. X * STEVIE - Simply Try this Editor for VI Enthusiasts
  2155. X *
  2156. X * Code Contributions By : Tim Thompson           twitch!tjt
  2157. X *                         Tony Andrews           onecom!wldrdg!tony 
  2158. X *                         G. R. (Fred) Walter    watmath!watcgl!grwalter 
  2159. X */
  2160. X
  2161. X#include "stevie.h"
  2162. X
  2163. X/*
  2164. X * inc(p) 
  2165. X *
  2166. X * Increment the line pointer 'p' crossing line boundaries as necessary. Return
  2167. X * 1 when crossing a line, -1 when at end of file, 0 otherwise. 
  2168. X */
  2169. Xint
  2170. Xinc(lp)
  2171. X    register LPtr  *lp;
  2172. X{
  2173. X    register char  *p = &(lp->linep->s[lp->index]);
  2174. X
  2175. X    if (*p != NUL) {        /* still within line */
  2176. X    lp->index++;
  2177. X    return ((p[1] != NUL) ? 0 : 1);
  2178. X    }
  2179. X    if (lp->linep->next != Fileend->linep) {    /* there is a next line */
  2180. X    lp->index = 0;
  2181. X    lp->linep = lp->linep->next;
  2182. X    return 1;
  2183. X    }
  2184. X    return -1;
  2185. X}
  2186. SHAR_EOF
  2187. echo "extracting keymap.h"
  2188. sed 's/^X//' << \SHAR_EOF > keymap.h
  2189. X/*
  2190. X * STEVIE - Simply Try this Editor for VI Enthusiasts
  2191. X *
  2192. X * Code Contributions By : Tim Thompson           twitch!tjt
  2193. X *                         Tony Andrews           onecom!wldrdg!tony 
  2194. X *                         G. R. (Fred) Walter    watmath!watcgl!grwalter 
  2195. X */
  2196. X
  2197. X/*
  2198. X * Keycode definitions for special keys 
  2199. X *
  2200. X * On systems that have any of these keys, the routine 'inchar' in the
  2201. X * machine-dependent code should return one of the codes here. 
  2202. X */
  2203. X
  2204. X#define    K_CGRAVE    0x1e    /* control grave accent */
  2205. X
  2206. X#define    K_HELP        0x80
  2207. X#define    K_UNDO        0x81
  2208. X#define    K_INSERT    0x82
  2209. X#define    K_HOME        0x83
  2210. X#define    K_UARROW    0x84
  2211. X#define    K_DARROW    0x85
  2212. X#define    K_LARROW    0x86
  2213. X#define    K_RARROW    0x87
  2214. X#define    K_SUARROW    0x88
  2215. X#define    K_SDARROW    0x89
  2216. X#define    K_SLARROW    0x8a
  2217. X#define    K_SRARROW    0x8b
  2218. X
  2219. X#define    K_F1        0x8c    /* function keys */
  2220. X#define    K_F2        0x8d
  2221. X#define    K_F3        0x8e
  2222. X#define    K_F4        0x8f
  2223. X#define    K_F5        0x90
  2224. X#define    K_F6        0x91
  2225. X#define    K_F7        0x92
  2226. X#define    K_F8        0x93
  2227. X#define    K_F9        0x94
  2228. X#define    K_F10        0x95
  2229. X
  2230. X#define    K_SF1        0x96    /* shifted function keys */
  2231. X#define    K_SF2        0x97
  2232. X#define    K_SF3        0x98
  2233. X#define    K_SF4        0x99
  2234. X#define    K_SF5        0x9a
  2235. X#define    K_SF6        0x9b
  2236. X#define    K_SF7        0x9c
  2237. X#define    K_SF8        0x9d
  2238. X#define    K_SF9        0x9e
  2239. X#define    K_SF10        0x9f
  2240. SHAR_EOF
  2241. echo "extracting linefunc.c"
  2242. sed 's/^X//' << \SHAR_EOF > linefunc.c
  2243. X/*
  2244. X * STEVIE - Simply Try this Editor for VI Enthusiasts
  2245. X *
  2246. X * Code Contributions By : Tim Thompson           twitch!tjt
  2247. X *                         Tony Andrews           onecom!wldrdg!tony 
  2248. X *                         G. R. (Fred) Walter    watmath!watcgl!grwalter 
  2249. X */
  2250. X
  2251. X#include "stevie.h"
  2252. X
  2253. X/*
  2254. X * nextline(curr) 
  2255. X *
  2256. X * Return a pointer to the beginning of the next line after the one referenced
  2257. X * by 'curr'. Return NULL if there is no next line (at EOF). 
  2258. X */
  2259. X
  2260. XLPtr           *
  2261. Xnextline(curr)
  2262. X    LPtr           *curr;
  2263. X{
  2264. X    static LPtr     next;
  2265. X
  2266. X    if (curr != NULL) {
  2267. X    if (curr->linep->next != Fileend->linep) {
  2268. X        next.index = 0;
  2269. X        next.linep = curr->linep->next;
  2270. X        return &next;
  2271. X    }
  2272. X    }
  2273. X    return (LPtr *) NULL;
  2274. X}
  2275. X
  2276. X/*
  2277. X * prevline(curr) 
  2278. X *
  2279. X * Return a pointer to the beginning of the line before the one referenced by
  2280. X * 'curr'. Return NULL if there is no prior line. 
  2281. X */
  2282. X
  2283. XLPtr           *
  2284. Xprevline(curr)
  2285. X    LPtr           *curr;
  2286. X{
  2287. X    static LPtr     prev;
  2288. X
  2289. X    if (curr != NULL) {
  2290. X    if (curr->linep->prev != Filetop->linep) {
  2291. X        prev.index = 0;
  2292. X        prev.linep = curr->linep->prev;
  2293. X        return &prev;
  2294. X    }
  2295. X    }
  2296. X    return (LPtr *) NULL;
  2297. X}
  2298. X
  2299. X/*
  2300. X * coladvance(p,col) 
  2301. X *
  2302. X * Try to advance to the specified column, starting at p. 
  2303. X */
  2304. X
  2305. Xvoid
  2306. Xcoladvance(p, want_col)
  2307. X    register LPtr  *p;
  2308. X    register int    want_col;
  2309. X{
  2310. X    register char   c;
  2311. X    register int    col;
  2312. X    register int    incr;
  2313. X
  2314. X    if (gchar(p) != NUL) {    /* already at the end of line */
  2315. X    for (col = 0; want_col > 0;) {
  2316. X        c = gchar(p);
  2317. X        if (c == TAB && !P(P_LS))
  2318. X        incr = (P(P_TS) - col % P(P_TS));
  2319. X        else
  2320. X        incr = chars[c].ch_size;
  2321. X        want_col -= incr;
  2322. X        col += incr;
  2323. X
  2324. X        /* Don't go past the end of the file or the line. */
  2325. X        if (inc(p)) {
  2326. X        dec(p);
  2327. X        break;
  2328. X        }
  2329. X    }
  2330. X    }
  2331. X}
  2332. SHAR_EOF
  2333. echo "extracting macros.h"
  2334. sed 's/^X//' << \SHAR_EOF > macros.h
  2335. X/*
  2336. X * STEVIE - Simply Try this Editor for VI Enthusiasts
  2337. X *
  2338. X * Code Contributions By : Tim Thompson           twitch!tjt
  2339. X *                         Tony Andrews           onecom!wldrdg!tony 
  2340. X *                         G. R. (Fred) Walter    watmath!watcgl!grwalter 
  2341. X */
  2342. X
  2343. X/*
  2344. X * gchar(lp) - get the character at position "lp" 
  2345. X */
  2346. X#define gchar(lp) ((lp)->linep->s[(lp)->index])
  2347. X
  2348. X/*
  2349. X * pchar(lp, c) - put character 'c' at position 'lp' 
  2350. X */
  2351. X#define pchar(lp, c) ((lp)->linep->s[(lp)->index] = (c))
  2352. X
  2353. X/*
  2354. X * pswap(a, b) - swap two position pointers 
  2355. X */
  2356. X#define pswap(a, b) { LPtr pswaptmp; pswaptmp = a; a = b; b = pswaptmp; }
  2357. X
  2358. X/*
  2359. X * Position comparisons 
  2360. X */
  2361. X#define lt(a, b) ((LINEOF(a) != LINEOF(b)) \
  2362. X                   ? (LINEOF(a) < LINEOF(b)) : ((a)->index < (b)->index))
  2363. X
  2364. X#define ltoreq(a, b) ((LINEOF(a) != LINEOF(b)) \
  2365. X                   ? (LINEOF(a) < LINEOF(b)) : ((a)->index <= (b)->index))
  2366. X
  2367. X#define gt(a, b) ((LINEOF(a) != LINEOF(b)) \
  2368. X                   ? (LINEOF(a) > LINEOF(b)) : ((a)->index > (b)->index))
  2369. X
  2370. X#define gtoreq(a, b) ((LINEOF(a) != LINEOF(b)) \
  2371. X                   ? (LINEOF(a) > LINEOF(b)) : ((a)->index >= (b)->index))
  2372. X
  2373. X#define equal(a, b) (((a)->linep == (b)->linep) && ((a)->index == (b)->index))
  2374. X
  2375. X/*
  2376. X * anyinput
  2377. X *
  2378. X * Return non-zero if input is pending.
  2379. X */
  2380. X#define anyinput() (Readbuffptr != NULL)
  2381. X
  2382. X/*
  2383. X * buf1line() - return TRUE if there is only one line in file buffer
  2384. X */
  2385. X#define buf1line() (Filemem->linep->next == Fileend->linep)
  2386. X
  2387. X/*
  2388. X * bufempty() - return TRUE if the file buffer is empty 
  2389. X */
  2390. X#define bufempty() (buf1line() && Filemem->linep->s[0] == NUL)
  2391. X
  2392. X/*
  2393. X * lineempty() - return TRUE if the line is empty 
  2394. X */
  2395. X#define lineempty(p) ((p)->linep->s[0] == NUL)
  2396. X
  2397. X/*
  2398. X * startofline() - return TRUE if the given position is at start of line 
  2399. X */
  2400. X#define startofline(p) ((p)->index == 0)
  2401. X
  2402. X/*
  2403. X * endofline() - return TRUE if the given position is at end of line 
  2404. X *
  2405. X * This routine will probably never be called with a position resting on the NUL
  2406. X * byte, but handle it correctly in case it happens. 
  2407. X */
  2408. X#define endofline(p) \
  2409. X     ((p)->linep->s[(p)->index] == NUL || (p)->linep->s[(p)->index + 1] == NUL)
  2410. X
  2411. X/*
  2412. X * RowNumber() - return the row number (if no UndoInProgress)
  2413. X */
  2414. X#define RowNumber(p) (UndoInProgress ? 0 : cntllines(Filemem, (p)))
  2415. SHAR_EOF
  2416. echo "extracting main.c"
  2417. sed 's/^X//' << \SHAR_EOF > main.c
  2418. X/*
  2419. X * STEVIE - Simply Try this Editor for VI Enthusiasts
  2420. X *
  2421. X * Code Contributions By : Tim Thompson           twitch!tjt
  2422. X *                         Tony Andrews           onecom!wldrdg!tony 
  2423. X *                         G. R. (Fred) Walter    watmath!watcgl!grwalter 
  2424. X */
  2425. X
  2426. X#ifdef AMIGA
  2427. X# include <proto/exec.h>
  2428. X#endif
  2429. X
  2430. X#include "stevie.h"
  2431. X
  2432. Xint             Rows;        /* Number of Rows and Columns */
  2433. Xint             Columns;    /* in the current window. */
  2434. X
  2435. Xint             CheckTopcharAndBotchar = FALSE;
  2436. Xint             MustUpdateBotchar = FALSE;
  2437. Xint             ValidToCurschar = FALSE;
  2438. Xint             LineNotValid = FALSE;
  2439. X
  2440. Xint             NumLineSizes = -1;    /* # of active LineSizes */
  2441. XLINE          **LinePointers = NULL;    /* Pointer to the line for LineSizes */
  2442. Xchar           *LineSizes = NULL;    /* Size of a line (pline output) */
  2443. X
  2444. Xchar           *Filename = NULL;/* Current file name */
  2445. X
  2446. XLPtr           *Filemem;    /* The contents of the file, as a single
  2447. X                 * array. */
  2448. XLPtr           *Filetop;    /* Line 'above' the start of the file */
  2449. X
  2450. XLPtr           *Fileend;    /* Pointer to the end of the file in Filemem.
  2451. X                 * (It points to the byte AFTER the last
  2452. X                 * byte.) */
  2453. X
  2454. XLPtr           *Topchar;    /* Pointer to the byte in Filemem which is in
  2455. X                 * the upper left corner of the screen. */
  2456. X
  2457. XLPtr           *Botchar;    /* Pointer to the byte in Filemem which is
  2458. X                 * just off the bottom of the screen. */
  2459. X
  2460. XLPtr           *Curschar;    /* Pointer to byte in Filemem at which the
  2461. X                 * cursor is currently placed. */
  2462. X
  2463. Xint             Curscol;    /* Current position of cursor (column) */
  2464. Xint             Cursrow;    /* Current position of cursor (row) */
  2465. X
  2466. Xint             Cursvcol;    /* Current virtual column, the column number
  2467. X                 * of the file's actual line, as opposed to
  2468. X                 * the column number we're at on the screen.
  2469. X                 * This makes a difference on lines that span
  2470. X                 * more than one screen line. */
  2471. X
  2472. Xint             Curswant = 0;    /* The column we'd like to be at. This is
  2473. X                 * used try to stay in the same column
  2474. X                 * through up/down cursor motions. */
  2475. X
  2476. Xbool_t          set_want_col;    /* If set, then update Curswant the next time
  2477. X                 * through cursupdate() to the current
  2478. X                 * virtual column. */
  2479. X
  2480. Xint             State = NORMAL;    /* This is the current state of the command
  2481. X                 * interpreter. */
  2482. X
  2483. Xint             Prenum = 0;    /* The (optional) number before a command. */
  2484. X
  2485. XLPtr           *Insstart;    /* This is where the latest insert/append
  2486. X                 * mode started. */
  2487. X
  2488. Xbool_t          Changed = FALSE;/* Set to TRUE if something in the file has
  2489. X                 * been changed and not written out. */
  2490. X
  2491. Xchar           *IObuff;        /* file reads are done, one line at a time,
  2492. X                 * into this buffer; as well as sprintf's */
  2493. X
  2494. Xchar           *Insbuffptr = NULL;
  2495. Xchar           *Insbuff;    /* Each insertion gets stuffed into this
  2496. X                 * buffer. */
  2497. X
  2498. Xchar           *Readbuffptr = NULL;
  2499. Xchar           *Readbuff;    /* Having this buffer allows STEVIE to easily
  2500. X                 * make itself do commands */
  2501. X
  2502. Xchar           *Redobuffptr = NULL;
  2503. Xchar           *Redobuff;    /* Each command should stuff characters into
  2504. X                 * this buffer that will re-execute itself. */
  2505. X
  2506. Xbool_t          UndoInProgress = FALSE;    /* Set to TRUE if undo'ing */
  2507. Xchar           *Undobuffptr = NULL;
  2508. Xchar           *Undobuff;    /* Each command should stuff characters into
  2509. X                 * this buffer that will undo its effects. */
  2510. X
  2511. Xchar           *UndoUndobuffptr = NULL;
  2512. Xchar           *UndoUndobuff;    /* Each command should stuff characters into
  2513. X                 * this buffer that will undo its undo. */
  2514. X
  2515. Xchar           *Yankbuffptr = NULL;
  2516. Xchar           *Yankbuff;    /* Yank buffer */
  2517. X
  2518. Xchar            last_command = NUL;    /* last command */
  2519. Xchar            last_command_char = NUL;    /* character needed to undo
  2520. X                         * last command */
  2521. X
  2522. Xbool_t          RedrawingDisabled = FALSE;    /* Set to TRUE if undo'ing or
  2523. X                         * put'ing */
  2524. X
  2525. Xchar          **files;        /* list of input files */
  2526. Xint             numfiles;    /* number of input files */
  2527. Xint             curfile;    /* number of the current file */
  2528. X
  2529. Xstatic void
  2530. Xusage()
  2531. X{
  2532. X    fprintf(stderr, "usage: stevie [file ...]\n");
  2533. X    fprintf(stderr, "       stevie -t tag\n");
  2534. X    fprintf(stderr, "       stevie +[num] file\n");
  2535. X    fprintf(stderr, "       stevie +/pat  file\n");
  2536. X    exit(1);
  2537. X}
  2538. X
  2539. X#ifdef AMIGA
  2540. Xvoid
  2541. X#else
  2542. Xint
  2543. X#endif
  2544. Xmain(argc, argv)
  2545. X    int             argc;
  2546. X    char          **argv;
  2547. X{
  2548. X    char           *initstr;    /* init string from the environment */
  2549. X    char           *tag = NULL;    /* tag from command line */
  2550. X    char           *pat = NULL;    /* pattern from command line */
  2551. X    int             line = -1;    /* line number from command line */
  2552. X
  2553. X    int             atoi();
  2554. X    char           *getenv();
  2555. X
  2556. X#ifdef AMIGA
  2557. X    {
  2558. X    struct Library *DosBase;/* Used for checking version */
  2559. X
  2560. X    DosBase = OpenLibrary("dos.library", 33);
  2561. X    if (!DosBase) {
  2562. X        fprintf(stderr,
  2563. X         "\nSTEVIE requires Version 33 or later of dos.library.\n");
  2564. X        exit(2);
  2565. X    } else {
  2566. X        CloseLibrary(DosBase);
  2567. X    }
  2568. X
  2569. X/*
  2570. X * I don't think STEVIE should be exited with a break.
  2571. X */
  2572. X    (void) signal(SIGINT, SIG_IGN);
  2573. X    }
  2574. X#endif
  2575. X
  2576. X    /*
  2577. X     * Process the command line arguments. 
  2578. X     */
  2579. X    if (argc > 1) {
  2580. X    switch (argv[1][0]) {
  2581. X
  2582. X      case '-':        /* -t tag */
  2583. X        if (argv[1][1] != 't')
  2584. X        usage();
  2585. X
  2586. X        if (argv[2] == NULL)
  2587. X        usage();
  2588. X
  2589. X        Filename = NULL;
  2590. X        tag = argv[2];
  2591. X        numfiles = 1;
  2592. X        break;
  2593. X
  2594. X      case '+':        /* +n or +/pat */
  2595. X        if (argv[1][1] == '/') {
  2596. X        if (argv[2] == NULL)
  2597. X            usage();
  2598. X        Filename = strsave(argv[2]);
  2599. X        pat = &(argv[1][1]);
  2600. X        numfiles = 1;
  2601. X
  2602. X        } else if (isdigit(argv[1][1]) || argv[1][1] == NUL) {
  2603. X        if (argv[2] == NULL)
  2604. X            usage();
  2605. X        Filename = strsave(argv[2]);
  2606. X        numfiles = 1;
  2607. X
  2608. X        line = (isdigit(argv[1][1])) ?
  2609. X            atoi(&(argv[1][1])) : 0;
  2610. X        } else
  2611. X        usage();
  2612. X
  2613. X        break;
  2614. X
  2615. X      default:        /* must be a file name */
  2616. X        Filename = strsave(argv[1]);
  2617. X        files = &(argv[1]);
  2618. X        numfiles = argc - 1;
  2619. X        break;
  2620. X    }
  2621. X    } else {
  2622. X    Filename = NULL;
  2623. X    numfiles = 1;
  2624. X    }
  2625. X    curfile = 0;
  2626. X
  2627. X    windinit();
  2628. X
  2629. X    /*
  2630. X     * Allocate LPtr structures for all the various position pointers and for
  2631. X     * the many buffers. 
  2632. X     */
  2633. X    Filetop = (LPtr *) alloc((unsigned) sizeof(LPtr));
  2634. X    Filemem = (LPtr *) alloc((unsigned) sizeof(LPtr));
  2635. X    Fileend = (LPtr *) alloc((unsigned) sizeof(LPtr));
  2636. X    Topchar = (LPtr *) alloc((unsigned) sizeof(LPtr));
  2637. X    Curschar = (LPtr *) alloc((unsigned) sizeof(LPtr));
  2638. X    Botchar = (LPtr *) alloc((unsigned) sizeof(LPtr));
  2639. X    Insstart = (LPtr *) alloc((unsigned) sizeof(LPtr));
  2640. X    IObuff = alloc(IOSIZE);
  2641. X    Insbuff = alloc(INSERT_SIZE);
  2642. X    Readbuff = alloc(READSIZE);
  2643. X    Redobuff = alloc(REDO_UNDO_SIZE);
  2644. X    Undobuff = alloc(REDO_UNDO_SIZE);
  2645. X    UndoUndobuff = alloc(REDO_UNDO_SIZE);
  2646. X    Yankbuff = alloc(YANKSIZE);
  2647. X    if (Filetop == NULL ||
  2648. X    Filemem == NULL ||
  2649. X    Fileend == NULL ||
  2650. X    Topchar == NULL ||
  2651. X    Curschar == NULL ||
  2652. X    Botchar == NULL ||
  2653. X    Insstart == NULL ||
  2654. X    IObuff == NULL ||
  2655. X    Insbuff == NULL ||
  2656. X    Readbuff == NULL ||
  2657. X    Redobuff == NULL ||
  2658. X    Undobuff == NULL ||
  2659. X    UndoUndobuff == NULL ||
  2660. X    Yankbuff == NULL) {
  2661. X    fprintf(stderr, "Can't allocate data structures\n");
  2662. X    windexit(0);
  2663. X    }
  2664. X    screenalloc();
  2665. X    filealloc();        /* Initialize Filemem, Filetop & Fileend */
  2666. X
  2667. X    s_clear();
  2668. X
  2669. X    initstr = getenv("EXINIT");
  2670. X    if (initstr != NULL) {
  2671. X    char           *lp, buf[128];
  2672. X
  2673. X    lp = getenv("LINES");
  2674. X    if (lp != NULL) {
  2675. X        sprintf(buf, "%s lines=%s", initstr, lp);
  2676. X        readcmdline(':', buf);
  2677. X    } else
  2678. X        readcmdline(':', initstr);
  2679. X    }
  2680. X    if (Filename != NULL) {
  2681. X    if (readfile(Filename, Filemem, FALSE))
  2682. X        filemess("[New File]");
  2683. X    } else
  2684. X    msg("Empty Buffer");
  2685. X
  2686. X    setpcmark();
  2687. X
  2688. X    if (tag) {
  2689. X    stuffReadbuff(":ta ");
  2690. X    stuffReadbuff(tag);
  2691. X    stuffReadbuff("\n");
  2692. X    } else if (pat) {
  2693. X    stuffReadbuff(pat);
  2694. X    stuffReadbuff("\n");
  2695. X    } else if (line >= 0) {
  2696. X    if (line > 0)
  2697. X        stuffnumReadbuff(line);
  2698. X    stuffReadbuff("G");
  2699. X    }
  2700. X    edit();
  2701. X    /* NOTREACHED */
  2702. X    /* windexit(0); */
  2703. X}
  2704. X
  2705. Xvoid
  2706. XstuffReadbuff(s)
  2707. X    char           *s;
  2708. X{
  2709. X    if (Readbuffptr == NULL) {
  2710. X    if ((strlen(s) + 1) < READSIZE) {
  2711. X        strcpy(Readbuff, s);
  2712. X        Readbuffptr = Readbuff;
  2713. X        return;
  2714. X    }
  2715. X    } else if ((strlen(Readbuff) + (strlen(s) + 1)) < READSIZE) {
  2716. X    strcat(Readbuff, s);
  2717. X    return;
  2718. X    }
  2719. X    emsg("Couldn't stuffReadbuff() - clearing Readbuff\n");
  2720. X    *Readbuff = NUL;
  2721. X    Readbuffptr = NULL;
  2722. X}
  2723. X
  2724. Xvoid
  2725. XstuffnumReadbuff(n)
  2726. X    int             n;
  2727. X{
  2728. X    char            buf[32];
  2729. X
  2730. X    sprintf(buf, "%d", n);
  2731. X    stuffReadbuff(buf);
  2732. X}
  2733. X
  2734. X/* OPTRESULT */
  2735. Xchar
  2736. Xvgetc()
  2737. X{
  2738. X    int             c;
  2739. X
  2740. X    /*
  2741. X     * inchar() may map special keys by using stuffReadbuff(). If it does so,
  2742. X     * it returns -1 so we know to loop here to get a real char. 
  2743. X     */
  2744. X    do {
  2745. X    if (Readbuffptr != NULL) {
  2746. X        char            nextc = *Readbuffptr++;
  2747. X
  2748. X        if (*Readbuffptr == NUL) {
  2749. X        *Readbuff = NUL;
  2750. X        Readbuffptr = NULL;
  2751. X        }
  2752. X        return (nextc);
  2753. X    }
  2754. X    c = inchar();
  2755. X    } while (c == -1);
  2756. X
  2757. X    return (char) c;
  2758. X}
  2759. X
  2760. Xchar
  2761. Xvpeekc()
  2762. X{
  2763. X    if (Readbuffptr != NULL)
  2764. X    return (*Readbuffptr);
  2765. X    return (NUL);
  2766. X}
  2767. SHAR_EOF
  2768. echo "End of archive 2 (of 6)"
  2769. # if you want to concatenate archives, remove anything after this line
  2770. exit
  2771.